3

I am generating a PDF invoice report using OpenPDF. On the PDF, I have to set a rectangular block for header/footer on every page. I have used the HeaderFooter class to add header/footer on every page but this works only for a Phrase.

HeaderFooter header = new HeaderFooter(new Phrase("This is a Header."), false);

Is there any way to set a rectangular block with height and width for header/footer using HeaderFooter class?

This is what I am expecting on every page:

expected output

Matt
  • 12,848
  • 2
  • 31
  • 53
java_maestros
  • 296
  • 2
  • 13

1 Answers1

4

You can do this by creating your custom PdfPageEvent where you add the elements whenever a new page is finished (onEndPage-event). The simplest way of doing this is by extending PdfPageEventHelper in a standalone class or in an anonymous class. First, define and style your rectangles. Second, add them to the page using the PdfWriter inside the callback.

Here is a demo showing how to do it:

Document document = new Document(PageSize.A4, 40, 40, 200, 200);
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("output.pdf"));

// footer
final Rectangle footer = new Rectangle(30, 30, PageSize.A4.getRight(30), 180);
footer.setBorder(Rectangle.BOX);
footer.setBorderColor(Color.BLACK);
footer.setBorderWidth(2);

// header
final Rectangle header = new Rectangle(footer);
header.setTop(PageSize.A4.getTop(30));
header.setBottom(PageSize.A4.getTop(180));

// content-box
final Rectangle box = new Rectangle(footer);
box.setTop(document.top());
box.setBottom(document.bottom());

// create and register page event to add the rectangles
writer.setPageEvent(new PdfPageEventHelper() {
    @Override
    public void onEndPage(PdfWriter writer, Document document) {
        PdfContentByte cb = writer.getDirectContent();
        cb.rectangle(header);
        cb.rectangle(footer);
        cb.rectangle(box);
    }
});

document.open();
document.add(new Paragraph(LOREM_IPSUM)); // just some constant filler text
document.close();

The result looks like this:

result

Matt
  • 12,848
  • 2
  • 31
  • 53
  • Just two notes, the iText developers used to recommend not adding content in `onStartPage`, only in `onEndPage`, and never to the `Document` but always to the `PdfWriter`. Adding to `Document` in `onStartPage` can in boundary consition situations cause unwanted artifacts. – mkl Jul 18 '21 at 17:56
  • 2
    @mkl I edited my answer to add the content in *onEndPage* using the *PdfWriter* as you proposed. Thanks for making me aware of these facts, I really appreciate it. Maybe these notes could be added to the JavaDoc of OpenPDF for future reference. – Matt Jul 18 '21 at 18:21
  • Hi Matt, how the content of so created header and footer can be written? Thanks for your support – lx78 Apr 06 '23 at 16:35
  • @lx78 See the second last line in the example code `document.add(new Paragraph(LOREM_IPSUM));` – Matt Apr 11 '23 at 20:35
  • @Matt I would like to write also into header and footer, not only to the document. – lx78 Apr 13 '23 at 09:47