iText pdf library
Website search

How to add HTML headers and footers to a page?

Why is there an error when there are 2+ pages?

We want to add HTML headers and footers to a document. Currently, we have extended PdfPageEventHelper and overriden the onStartPage() and onEndPage() methods. This works fine for the first page, but it throws a RuntimeWorkerException when we get to 2+ pages.


    void onStartPage(PdfWriter writer, Document document) {
        InputStream is = new ByteArrayInputStream(header?.getBytes());
        XMLWorkerHelper.getInstance().parseXHtml(writer, document, is);
    void onEndPage(PdfWriter writer, Document document) {
        InputStream is = new ByteArrayInputStream(footer?.getBytes());
        XMLWorkerHelper.getInstance().parseXHtml(writer, document, is);


Posted on StackOverflow on Oct 28, 2015 by froi

It is forbidden to add content in the onStartPage() event in general. It is forbidden to add content to the document object in the onEndPage(). You should add your header and your footer in the onEndPage() method using PdfWriter, NOT document. Also: you are wasting plenty of CPU by parsing the HTML over and over again.

Please take a look at the HtmlHeaderFooter example.

It has two snippets of HTML, one for the header, one for the footer.

public static final String HEADER =
    "<table width=\"100%\" border=\"0\"><tr><td>Header</td><td align=\"right\">Some title</td></tr></table>";
public static final String FOOTER =
    "<table width=\"100%\" border=\"0\"><tr><td>Footer</td><td align=\"right\">Some title</td></tr></table>";

Note that there are better ways to describe the header and footer than by using HTML, but maybe it's one of your requirements.

We will read these HTML snippets only once in our page event and then we'll render the elements over and over again on every page:

public class HeaderFooter extends PdfPageEventHelper {
    protected ElementList header;
    protected ElementList footer;
    public HeaderFooter() throws IOException {
        header = XMLWorkerHelper.parseToElementList(HEADER, null);
        footer = XMLWorkerHelper.parseToElementList(FOOTER, null);
    public void onEndPage(PdfWriter writer, Document document) {
        try {
            ColumnText ct = new ColumnText(writer.getDirectContent());
            ct.setSimpleColumn(new Rectangle(36, 832, 559, 810));
            for (Element e : header) {
            ct.setSimpleColumn(new Rectangle(36, 10, 559, 32));
            for (Element e : footer) {
        } catch (DocumentException de) {
            throw new ExceptionConverter(de);

Do you see the mechanism we use to add the Element objects obtained from XML Worker? We create a ColumnText object that will write to the direct content of the writer (using the document is forbidden). We define a Rectangle and we are using go() to render the elements.

The results is shown in html_header_footer.pdf.


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