Create Index File(TOC) for merged pdf using itext library in java
itext, itextpdf, java, pdf
Solution
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:
chunk = new Chunk(String.format("Page %d", pageNo));
if (i == 1)
chunk.setLocalDestination("p" + pageNo);
ColumnText.showTextAligned(stamp.getUnderContent(),
Element.ALIGN_RIGHT, new Phrase(chunk), 559, 810, 0);
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:
PdfReader reader = new PdfReader(SRC3);
page = copy.getImportedPage(reader, 1);
stamp = copy.createPageStamp(page);
Paragraph p;
PdfAction action;
PdfAnnotation link;
float y = 770;
ColumnText ct = new ColumnText(stamp.getOverContent());
ct.setSimpleColumn(36, 36, 559, y);
for (Map.Entry<Integer, String> entry : toc.entrySet()) {
p = new Paragraph(entry.getValue());
p.add(new Chunk(new DottedLineSeparator()));
p.add(String.valueOf(entry.getKey()));
ct.addElement(p);
ct.go();
action = PdfAction.gotoLocalPage("p" + entry.getKey(), false);
link = new PdfAnnotation(copy, 36, ct.getYLine(), 559, y, action);
stamp.addAnnotation(link);
y = ct.getYLine();
}
ct.go();
stamp.alterContents();
copy.addPage(page);
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:
reader = new PdfReader(baos.toByteArray());
n = reader.getNumberOfPages();
reader.selectPages(String.format("%d, 1-%d", n, n-1));
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(filename));
stamper.close();
Problem
I am using iText to create a single PDF by merging a number of PDFs using PDFCopy. 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. Code to merge pdf ``` Document PDFJoinInJava = new Document(); PdfCopy PDFCombiner = new PdfCopy(PDFJoinInJava, outputStream); PdfCopy.PageStamp stamp; PDFJoinInJava.open(); PdfReader ReadInputPDF; List<InputStream> pdfs = streamOfPDFFiles; List<PdfReader> readers = new ArrayList<PdfReader>(); int totalPages = 0; Iterator<InputStream> iteratorPDFs = pdfs.iterator(); for (; iteratorPDFs.hasNext(); pdfCounter++) { InputStream pdf = iteratorPDFs.next(); PdfReader pdfReader = new PdfReader(pdf); readers.add(pdfReader); totalPages += pdfReader.getNumberOfPages(); pdf.close(); } int number_of_pages; int currentPageNumber = 0; int pageOfCurrentReaderPDF = 0; Iterator<PdfReader> iteratorPDFReader = readers.iterator(); PdfImportedPage page; // Loop through the PDF files and add to the output. int count = 1; while (iteratorPDFReader.hasNext()) { PdfReader pdfReader = iteratorPDFReader.next(); count++; number_of_pages = pdfReader.getNumberOfPages(); // Create a new page in the target for each source page. for (int pageNum = 0; pageNum < number_of_pages;) { currentPageNumber++; pageOfCurrentReaderPDF++; page = PDFCombiner.getImportedPage(pdfReader, ++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(); PDFCombiner.addPage(page); } } PDFJoinInJava.close(); ```