Skip to main content
Skip table of contents

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:

JAVA
protected void createPdf(String dest) throws Exception {
  PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
  Document doc = new Document(pdfDoc);

  TableHeaderEventHandler handler = new TableHeaderEventHandler(doc);
  pdfDoc.addEventHandler(PdfDocumentEvent.END_PAGE, handler);

  // Calculate top margin to be sure that the table will fit the margin.
  float topMargin = 20 + handler.getTableHeight();
  doc.setMargins(topMargin, 36, 36, 36);

  for (int i = 0; i < 50; i++) {
    doc.add(new Paragraph("Hello World!"));
  }

  doc.add(new AreaBreak());
  doc.add(new Paragraph("Hello World!"));
  doc.add(new AreaBreak());
  doc.add(new Paragraph("Hello World!"));

  doc.close();
}

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

JAVA
    pdfDoc.addEventHandler(PdfDocumentEvent.END_PAGE, handler);

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

JAVA
public class TableHeaderEventHandler extends AbstractPdfDocumentEventHandler {

  private Table table;
  private final float tableHeight;
  private final Document doc;

  public TableHeaderEventHandler(Document doc) {
    this.doc = doc;
    initTable();

    TableRenderer renderer = (TableRenderer) table.createRendererSubTree();
    renderer.setParent(new DocumentRenderer(doc));

    LayoutResult result = renderer.layout(
      new LayoutContext(new LayoutArea(0, PageSize.A4))
    );

    tableHeight = result.getOccupiedArea().getBBox().getHeight();
  }

  @Override
  public void onAcceptedEvent(AbstractPdfDocumentEvent currentEvent) {
    PdfDocumentEvent docEvent = (PdfDocumentEvent) currentEvent;
    PdfDocument pdfDoc = docEvent.getDocument();
    PdfPage page = docEvent.getPage();

    PdfCanvas canvas = new PdfCanvas(
      page.newContentStreamBefore(),
      page.getResources(),
      pdfDoc
    );

    PageSize pageSize = pdfDoc.getDefaultPageSize();

    float coordX = pageSize.getX() + doc.getLeftMargin();
    float coordY = pageSize.getTop() - doc.getTopMargin();
    float width = pageSize.getWidth() - doc.getLeftMargin() - doc.getRightMargin();
    float height = getTableHeight();

    Rectangle rect = new Rectangle(coordX, coordY, width, height);

    new Canvas(canvas, rect)
      .add(table)
      .close();
  }

  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:

JAVA
float topMargin = 20 + handler.getTableHeight();
doc.setMargins(topMargin, 36, 36, 36);

The result looks like this:

Header table and content: no overlap. Page 1.

Header table and content: no overlap. Page 2.

Now the content does not overlap the header.

Click Why does my header overlap with my content? - iText 5 PDF Library Explained if you want to see how to answer this question in iText 5.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.