Question

I am creating some PDF reports using iText in Java. According to the requirements, what I should do is to number pages in the format of page_number/page_numbers_in_total.

However, memory operations burden my project. Hence, I don't want to go over all the pages again in order to number them. Is there any method to achieve that?

Was it helpful?

Solution

Have a look at this example, which sets a similar header ("Page X of Y"):

You'll see that the onEndPage method prints the "Page X of ", and the onCloseDocument method sets the "Y" on all the pages through a PdfTemplate.

OTHER TIPS

The answer that is marker as correct worked for me. I've just spent a lot of time refactoring the code (font size, position) and making it applicable to all existing PDFs.

Notice that the the number of the page is in the bottom right corner of the page, and some optional text is in the left bottom corner.

Below is the code of class PageNumeration created using the previous comment for this purpose.

package demo;

import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.ExceptionConverter;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfTemplate;
import com.itextpdf.text.pdf.PdfWriter;

class PageNumeration extends PdfPageEventHelper {
/** The template with the total number of pages. */
PdfTemplate total;

private Font normal, normalSmall;
private Company company;

public PageNumeration (){
    try{
        this.normal = new Font(BaseFont.createFont(FONT, BaseFont.IDENTITY_H, BaseFont.EMBEDDED), 8);
        this.normalSmall = new Font(BaseFont.createFont(FONT, BaseFont.IDENTITY_H, BaseFont.EMBEDDED), 6);
    }
    catch (Exception e) {
        e.printStackTrace();
    }
}

/**
 * Creates the PdfTemplate that will hold the total number of pages.
 * @see com.itextpdf.text.pdf.PdfPageEventHelper#onOpenDocument(
 *      com.itextpdf.text.pdf.PdfWriter, com.itextpdf.text.Document)
 */
public void onOpenDocument(PdfWriter writer, Document document) {
    total = writer.getDirectContent().createTemplate(30, 12);
}

/**
 * Adds a header to every page
 * @see com.itextpdf.text.pdf.PdfPageEventHelper#onEndPage(
 *      com.itextpdf.text.pdf.PdfWriter, com.itextpdf.text.Document)
 */
public void onEndPage(PdfWriter writer, Document document) {
    PdfPTable table = new PdfPTable(3);
    try {
        table.setWidths(new int[]{24, 24, 2});
        table.getDefaultCell().setFixedHeight(10);
        table.getDefaultCell().setBorder(Rectangle.TOP);
        PdfPCell cell = new PdfPCell();
        cell.setBorder (0);
        cell.setBorderWidthTop (1);
        cell.setHorizontalAlignment(Element.ALIGN_LEFT);
        cell.setPhrase(new Phrase("some text", normalSmall));
        table.addCell(cell);

        cell = new PdfPCell();
        cell.setBorder (0);
        cell.setBorderWidthTop (1);
        cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
        cell.setPhrase(new Phrase(String.format("Page %d of", writer.getPageNumber()), normal));
        table.addCell(cell);

        cell = new PdfPCell(Image.getInstance(total));
        cell.setBorder (0);
        cell.setBorderWidthTop (1);
        table.addCell(cell);
        table.setTotalWidth(document.getPageSize().getWidth()
                - document.leftMargin() - document.rightMargin());
        table.writeSelectedRows(0, -1, document.leftMargin(),
                document.bottomMargin() - 15, writer.getDirectContent());
    }
    catch(DocumentException de) {
        throw new ExceptionConverter(de);
    }
}

/**
 * Fills out the total number of pages before the document is closed.
 * @see com.itextpdf.text.pdf.PdfPageEventHelper#onCloseDocument(
 *      com.itextpdf.text.pdf.PdfWriter, com.itextpdf.text.Document)
 */
public void onCloseDocument(PdfWriter writer, Document document) {
    ColumnText.showTextAligned(total, Element.ALIGN_LEFT,
            new Phrase(String.valueOf(writer.getPageNumber() - 1), normal),
            2, 2, 0);
    }
}  

After you have created this class just instance it in your PDF class and set the event just below the writer definition.

writer = PdfWriter.getInstance(document, new  FileOutputStream("somepath/somedir/file.pdf"));
PageNumeration event = new PageNumeration(this.company);
writer.setPageEvent(event);

Hope this helps.

you could handle page number with @page style sheet Like this @page { @top-right { content: "Page " counter(page) " of " counter(pages); } }

And when you need page number/Total page try with this: counter(page) "/" counter(pages)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top