简体   繁体   中英

Merge documents to create TOC in iText (Java)

When creating documents with iText that need a table of contents, I have usually used a process where I create the main document in memory, create the TOC as a separate document in memory (using dummy links), merge them as a third document, and then use a PdfStamper to reconcile the links into the document and write it to a file.

This works with all versions of iText except the most recent (5.5.6). I will include a simple program that does this process (the real programs are much more complex). When running this with iText 5.5.5 or earlier, it creates the desired document (2 pages with the first page containing text that provides a link to open the second page). With 5.5.6 the call to makeRemoteNamedDestinationsLocal causes an exception com.itextpdf.text.pdf.PdfDictionary cannot be cast to com.itextpdf.text.pdf.PdfArray .

As this had always worked until the latest version, I have some suspicion that this may be a bug in the newest version. Is this a bug, or am I doing something wrong? How should I do this task if it is not a bug? Additionally, how are bug reports usually submitted for iText? From the website, it looks like they expect a question to be submitted here as a report.

import com.itextpdf.text.pdf.*;
import com.itextpdf.text.pdf.draw.*;
import java.io.*;

// WORKS CORRECTLY USING itext version 5.5.5
// FAILS WITH 5.5.6
// CAUSES AN EXCEPTION 
// "com.itextpdf.text.pdf.PdfDictionary cannot be cast to com.itextpdf.text.pdf.PdfArray"
// with makeRemoteNamedDestinationsLocal()
public class testPdf {
    public static void main (String[] args) throws Exception {
        // Create simple document
        ByteArrayOutputStream main = new ByteArrayOutputStream();
        Document doc = new Document(new Rectangle(612f,792f),54f,54f,36f,36f);
        PdfWriter pdfwrite = PdfWriter.getInstance(doc,main);
        doc.open();
        doc.add(new Paragraph("Testing Page"));
        doc.close();

        // Create TOC document
        ByteArrayOutputStream two = new ByteArrayOutputStream();
        Document doc2 = new Document(new Rectangle(612f,792f),54f,54f,36f,36f);
        PdfWriter pdfwrite2 = PdfWriter.getInstance(doc2,two);      
        doc2.open();
        Chunk chn = new Chunk("<<-- Link To Testing Page -->>");
        chn.setRemoteGoto("DUMMY.PDF","page-num-1");
        doc2.add(new Paragraph(chn));
        doc2.close();

        // Merge documents
        ByteArrayOutputStream three = new ByteArrayOutputStream();
        PdfReader reader1 = new PdfReader(main.toByteArray());
        PdfReader reader2 = new PdfReader(two.toByteArray());
        Document doc3 = new Document();
        PdfCopy DocCopy = new PdfCopy(doc3,three);
        doc3.open();
        DocCopy.addPage(DocCopy.getImportedPage(reader2,1));
        DocCopy.addPage(DocCopy.getImportedPage(reader1,1));
        DocCopy.addNamedDestination("page-num-1",2,new PdfDestination(PdfDestination.FIT));
        doc3.close();

        // Fix references and write to file
        PdfReader finalReader = new PdfReader(three.toByteArray());
        // Fails on this line
        finalReader.makeRemoteNamedDestinationsLocal();
        PdfStamper stamper = new PdfStamper(finalReader,new FileOutputStream("Testing.pdf"));
        stamper.close();    
    }
}

You have detected a bug that was introduced in iText 5.5.6. This has already been fixed in our repository:

在此处输入图片说明

Thank you for reporting this bug. You can find the fix on github: https://github.com/itext/itextpdf/commit/eac1a4318e6c31b054e0726ad44d0da5b8a720c2

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM