iText pdf library
Website search

Why does my header overlap with my content?

I am using page events to create a header that consists of a table. This table is added to each page in my document, but unfortunately, it overlaps with the rest of my content. How can I avoid this?

Question inspired by the posts on StackOverflow dated February 17, 2016 by Abhimanyu Katoch and Herin

Please take a look at the TableHeader example adapted for iText 7.

In this example, I create a document with some "Hello World" content:

public void createPdf(String dest) throws IOException {
    PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
    Document doc = new Document(pdfDoc, PageSize.A4);
    TableHeaderEventHandler handler = new TableHeaderEventHandler(doc);
    pdfDoc.addEventHandler(PdfDocumentEvent.END_PAGE, handler);
    doc.setMargins(20 + handler.getTableHeight(), 36, 36, 36);
    for (int i = 0; i 

As you can see, I also define a TableHeaderEventHandler. I use this event as a page event:

    pdfDoc.addEventHandler(PdfDocumentEvent.END_PAGE, handler);

What does this mean? Let's take a look at the implementation of this event handler:

   public class TableHeaderEventHandler implements IEventHandler {
        protected Table table;
        protected float tableHeight;
        protected Document doc;

        public TableHeaderEventHandler(Document doc) {
            this.doc = doc;
            table = new Table(1);
            table.setWidth(doc.getPdfDocument().getDefaultPageSize().getRight() - doc.getPdfDocument().getDefaultPageSize().getLeft() - doc.getLeftMargin() - doc.getRightMargin());
            table.addCell("Header row 1");
            table.addCell("Header row 2");
            table.addCell("Header row 3");
            TableRenderer renderer = (TableRenderer) table.createRendererSubTree();
            renderer.setParent(new Document(new PdfDocument(new PdfWriter(new ByteArrayOutputStream()))).getRenderer());
            tableHeight = renderer.layout(new LayoutContext(new LayoutArea(0, PageSize.A4))).getOccupiedArea().getBBox().getHeight();
        }

        @Override
        public void handleEvent(Event event) {
            PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
            PdfDocument pdfDoc = docEvent.getDocument();
            PdfPage page = docEvent.getPage();
            PdfCanvas canvas = new PdfCanvas(page.newContentStreamBefore(), page.getResources(), pdfDoc);
            Rectangle rect = new Rectangle(pdfDoc.getDefaultPageSize().getX() + doc.getLeftMargin(),
                    pdfDoc.getDefaultPageSize().getTop() - doc.getTopMargin(), 100, getTableHeight());
            new Canvas(canvas, pdfDoc, rect)
                    .add(table);
        }

        public float getTableHeight() {
            return tableHeight;
        }
    }

You need the height of the table to set the right top margin for the document. When you create a TableHeaderEventHandler, the height of the rendered table is calculated in the constructor using layout() method. According to this value you will use this line:

doc.setMargins(20 + handler.getTableHeight(), 36, 36, 36);

The result looks like this:

Header table and content: no overlap. Page 1.

Header table and content: no overlap. Page 1.

Header table and content: no overlap. Page 2.

Header table and content: no overlap. Page 2.

Now the content does not overlap the header.

Click this link if you want to see how to answer this question in iText 5.



Contact

Still have questions? 

We're happy to answer your questions. Reach out to us and we'll get back to you shortly.

Contact us
Stay updated

Join 11,000+ subscribers and become an iText PDF expert by staying up to date with our new products, updates, tips, technical solutions and happenings.

Subscribe Now