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