Adding Header and Footer in PDF using iText in Java

When creating PDF documents, the first thing we usually do, is create a header and footer for every page. Adding an image to the header, helps to brand the product and/or business. At the bottom of the page we can optionally include a copyright symbol followed by some text. In the bottom right corner you can find the current page number, followed by the total number of pages. In this tutorial we demonstrate how to add a header and footer in a PDF document using iText.

IText Dependency

We use Maven, add the following maven dependency to your project, and Maven’ll resolve the dependencies automatically.

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.9</version>
</dependency>

Adding Header, Footer and Total Pages

The com.itextpdf.text.pdf.PdfPageEventHelper contains all the events that occur when iText is writing a PDF document. By extending from this class and overriding these methods, we can write additional data to the PDF document when these events occur. Let’s take a look at the events.

  1. onOpenDocument called when the document is opened. Perfect place to initialize certain variables.
  2. onEndPage is called when a page is finished, just before being written to the document. We can add the header and footer to every page inside the PDF document.
  3. onCloseDocument is called before the document’ll be closed. This is the event where we inject the total number of pages in to the previously created template.
package com.memorynotfound.pdf.itext;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import java.io.IOException;
import java.net.MalformedURLException;

public class HeaderFooterPageEvent extends PdfPageEventHelper {

    private PdfTemplate t;
    private Image total;

    public void onOpenDocument(PdfWriter writer, Document document) {
        t = writer.getDirectContent().createTemplate(30, 16);
        try {
            total = Image.getInstance(t);
            total.setRole(PdfName.ARTIFACT);
        } catch (DocumentException de) {
            throw new ExceptionConverter(de);
        }
    }

    @Override
    public void onEndPage(PdfWriter writer, Document document) {
        addHeader(writer);
        addFooter(writer);
    }

    private void addHeader(PdfWriter writer){
        PdfPTable header = new PdfPTable(2);
        try {
            // set defaults
            header.setWidths(new int[]{2, 24});
            header.setTotalWidth(527);
            header.setLockedWidth(true);
            header.getDefaultCell().setFixedHeight(40);
            header.getDefaultCell().setBorder(Rectangle.BOTTOM);
            header.getDefaultCell().setBorderColor(BaseColor.LIGHT_GRAY);

            // add image
            Image logo = Image.getInstance(HeaderFooterPageEvent.class.getResource("/memorynotfound-logo.jpg"));
            header.addCell(logo);

            // add text
            PdfPCell text = new PdfPCell();
            text.setPaddingBottom(15);
            text.setPaddingLeft(10);
            text.setBorder(Rectangle.BOTTOM);
            text.setBorderColor(BaseColor.LIGHT_GRAY);
            text.addElement(new Phrase("iText PDF Header Footer Example", new Font(Font.FontFamily.HELVETICA, 12)));
            text.addElement(new Phrase("http://memorynotfound.com", new Font(Font.FontFamily.HELVETICA, 8)));
            header.addCell(text);

            // write content
            header.writeSelectedRows(0, -1, 34, 803, writer.getDirectContent());
        } catch(DocumentException de) {
            throw new ExceptionConverter(de);
        } catch (MalformedURLException e) {
            throw new ExceptionConverter(e);
        } catch (IOException e) {
            throw new ExceptionConverter(e);
        }
    }

    private void addFooter(PdfWriter writer){
        PdfPTable footer = new PdfPTable(3);
        try {
            // set defaults
            footer.setWidths(new int[]{24, 2, 1});
            footer.setTotalWidth(527);
            footer.setLockedWidth(true);
            footer.getDefaultCell().setFixedHeight(40);
            footer.getDefaultCell().setBorder(Rectangle.TOP);
            footer.getDefaultCell().setBorderColor(BaseColor.LIGHT_GRAY);

            // add copyright
            footer.addCell(new Phrase("\u00A9 Memorynotfound.com", new Font(Font.FontFamily.HELVETICA, 12, Font.BOLD)));

            // add current page count
            footer.getDefaultCell().setHorizontalAlignment(Element.ALIGN_RIGHT);
            footer.addCell(new Phrase(String.format("Page %d of", writer.getPageNumber()), new Font(Font.FontFamily.HELVETICA, 8)));

            // add placeholder for total page count
            PdfPCell totalPageCount = new PdfPCell(total);
            totalPageCount.setBorder(Rectangle.TOP);
            totalPageCount.setBorderColor(BaseColor.LIGHT_GRAY);
            footer.addCell(totalPageCount);

            // write page
            PdfContentByte canvas = writer.getDirectContent();
            canvas.beginMarkedContentSequence(PdfName.ARTIFACT);
            footer.writeSelectedRows(0, -1, 34, 50, canvas);
            canvas.endMarkedContentSequence();
        } catch(DocumentException de) {
            throw new ExceptionConverter(de);
        }
    }

    public void onCloseDocument(PdfWriter writer, Document document) {
        int totalLength = String.valueOf(writer.getPageNumber()).length();
        int totalWidth = totalLength * 5;
        ColumnText.showTextAligned(t, Element.ALIGN_RIGHT,
                new Phrase(String.valueOf(writer.getPageNumber()), new Font(Font.FontFamily.HELVETICA, 8)),
                totalWidth, 6, 0);
    }
}

Adding Total Number of Pages

  • In the first event, onOpenDocument, we initialized the PdfTemplate variable. This variable is a placeholder in which we add the total number of pages digit. This is due to the fact, that we only know the total of pages when we are finished writing content to the pdf document.
  • Let’s immediately jump to the onCloseDocument event. In this event iText is about to close the document, meaning we know exactly on which page number the PdfWriter is currently on. First, we calculate the number of digits the page number has. We need to calculate the number of pixels to allocate. Using the current font we’ve calculated that each digit takes approximately 5 pixels. So by multiplying the total length of the page numbers by the total width of a single digit, we are allocating enough space. Finally, we insert the page number total in the perviously created PdfTemplate.

Adding the Header and Footer

  • In the onEndPage event, we are adding the header and footer to the PDF document. This event occurs every time a page has finished, just before being written to the document.
  • We created a addHeader method, which will obviously add a header to the document. In this method, we create a PdfTable with two columns. The first column is for the logo (image) and the second is for the text. We initialize the header with a fixed height, correct width and adding a border to the bottom. In the first column we add the image which is loaded from the src/main/resources folder. Next, we create a PdfCell in which we add two Phrase elements that contain text. Finally, we call the writeSelectedRows method that will write the PDFTable to the document at a fixed position.
  • The addFooter method does almost the same as the addHeader method. But notice, that we add the previously created PdfTemplate inside a PdfCell. This template acts like a placeholder in which we are injecting the total page number.

Adding copyright and symbols

We can add a copyright symbol to a PDF Document using the unicode character \u00A9.

Adding Page Event and Create PDF Document

When creating the PDF document, we simply add the previously created HeaderFooterPageEvent using the setPageEvent method of the PdfWriter.

package com.memorynotfound.pdf.itext;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.PdfWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class CreatePdfDocument {

    public static void main(String... args) throws FileNotFoundException, DocumentException {

        // create document
        Document document = new Document(PageSize.A4, 36, 36, 90, 36);
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("HeaderFooter.pdf"));

        // add header and footer
        HeaderFooterPageEvent event = new HeaderFooterPageEvent();
        writer.setPageEvent(event);

        // write to document
        document.open();
        document.add(new Paragraph("Adding a header to PDF Document using iText."));
        document.newPage();
        document.add(new Paragraph("Adding a footer to PDF Document using iText."));
        document.close();
    }
}

Output

Here you can see the result. The PDF document we generated contains a clean header with an image. The footer contains a copyright symbol on the left. On the bottom right you can see the current page number together with the total page number.

adding header footer itext pdf java header example

References

Download

You may also like...