Why does my header overlap with my content?
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 2.
Now the content does not overlap the header.
Click Why does my header overlap with my content? if you want to see how to answer this question in iText 5.