Skip to main content
Skip table of contents

How to create a TOC when merging documents?

I need to create a TOC (not bookmarks) at the beginning of this document with clickable links to the first pages of each of the source PDFs.

I'm doing the following:

 

Document document = new Document();
PdfCopy copy = new PdfCopy(document, outputStream);
PdfCopy.PageStamp stamp;
document.open();
PdfReader reader;
ListInputStream> pdfs = streamOfPDFFiles;
ListPdfReader> readers = new ArrayListPdfReader>();
IteratorInputStream> iteratorPDFs = pdfs.iterator();
for (; iteratorPDFs.hasNext(); pdfCounter++) {
    InputStream pdf = iteratorPDFs.next();
    reader = new PdfReader(pdf);
    readers.add(reader);
    pdf.close();
}
int currentPageNumber = 0;
IteratorPdfReader> readerIterator = readers.iterator();
PdfImportedPage page;
int count = 1;
while (readerIterator.hasNext()) {
    reader = readerIterator.next();
    count++;
    int number_of_pages = reader.getNumberOfPages();
    for (int pageNum = 0; pageNum  number_of_pages;) {
        currentPageNumber++;
        page = copy.getImportedPage(reader, ++pageNum);
        ColumnText.showTextAligned(stamp.getUnderContent(),
            Element.ALIGN_RIGHT, new Phrase(
                String.format("%d", currentPageNumber),
                new Font(FontFamily.TIMES_ROMAN,3)), 50, 50, 0);
        stamp.alterContents();
        copy.addPage(page);
    }
}
document.close();

 

Posted on StackOverflow on Feb 4, 2014 by Butani Vijay

You're asking for something that should be trivial, but that isn't. Please take a look at the MergeWithToc example. You'll see that your code to merge PDFs is correct, but in my example, I added one extra feature:

Text text = new Text(String.format("Page %d", pageNo));
entry.getValue().copyPagesTo(i, i, pdfDoc);
if (i == 1) {
    text.setDestination("p" + pageNo);
}
doc.add(new Paragraph(text).setFixedPosition(pageNo, 549, 810, 40));

For every first page, I define a named destination as a local destination. We use p followed by the page number as its name.

We'll use these named destinations in an extra page that will serve as a TOC:

PdfDocument tocDoc = new PdfDocument(new PdfReader(src3));
tocDoc.copyPagesTo(1, 1, pdfDoc);
tocDoc.close();
float y = 770;
for (Map.Entry entry : toc.entrySet()) {
    Paragraph p = new Paragraph();
    p.addTabStops(new TabStop(500, TabAlignment.LEFT, new DashedLine()));
    p.add(entry.getValue());
    p.add(new Tab());
    p.add(String.valueOf(entry.getKey()));
    p.setAction(PdfAction.createGoTo("p" + entry.getKey()));
    doc.add(p.setFixedPosition(pdfDoc.getNumberOfPages(), 36, y, 595 - 72));
    y -= 20;
}
for (PdfDocument srcDoc : filesToMerge.values()) {
    srcDoc.close();
}

In my example, I assume that the TOC fits on a single page. You'll have to keep track of the y value and create a new page if its value is lower than the bottom margin.

If you want the TOC to be the first page, you need to reorder the pages in a second go. This is shown in the MergeWithToc2 example.

Click How to create a TOC when merging documents? 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.