Crea file indice (TOC) per il pdf unito usando la libreria itext in java

Sto usando iText per creare un singolo PDF unendo un numero di PDF usando PDFCopy . Ho bisogno di creare un TOC (non i segnalibri) all’inizio di questo documento con collegamenti cliccabili alle prime pagine di ciascuno dei PDF di origine.

Codice per unire pdf

Document PDFJoinInJava = new Document(); PdfCopy PDFCombiner = new PdfCopy(PDFJoinInJava, outputStream); PdfCopy.PageStamp stamp; PDFJoinInJava.open(); PdfReader ReadInputPDF; List pdfs = streamOfPDFFiles; List readers = new ArrayList(); int totalPages = 0; Iterator 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 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(); 

Stai chiedendo qualcosa che dovrebbe essere banale, ma non lo è. Si prega di dare un’occhiata all’esempio MergeWithToc . Vedrai che il tuo codice per unire PDF è corretto, ma nel mio esempio, ho aggiunto una funzione in più:

 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); 

Per ogni prima pagina, definisco una destinazione con nome come destinazione locale. Usiamo p seguito dal numero di pagina come nome.

Useremo queste destinazioni nominate in una pagina aggiuntiva che fungerà da sumrio:

 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 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); 

Nel mio esempio, suppongo che il sumrio si adatti a una singola pagina. Dovrai tenere traccia del valore y e creare una nuova pagina se il suo valore è inferiore al margine inferiore.

Se si desidera che il sumrio sia la prima pagina, è necessario riordinare le pagine in un secondo passaggio. Questo è mostrato nell’esempio MergeWithToc2 :

 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();