Merging documents and create a Table of Contents

This is a code example of iText PDF, discover more.

30th October 2015
admin-marketing

Switch code for this example

MergeWithToc.java
  1. /**
  2.  * Example written by Bruno Lowagie in answer to:
  3.  * http://stackoverflow.com/questions/21548552/create-index-filetoc-for-merged-pdf-using-itext-library-in-java
  4.  *
  5.  * When concatenating documents, we add a named destination every time
  6.  * a new document is started. After we've finished merging, we add an extra
  7.  * page with the table of contents and links to the named destinations.
  8.  */
  9. package sandbox.merge;
  10.  
  11. import com.itextpdf.text.Chunk;
  12. import com.itextpdf.text.Document;
  13. import com.itextpdf.text.DocumentException;
  14. import com.itextpdf.text.Element;
  15. import com.itextpdf.text.Paragraph;
  16. import com.itextpdf.text.Phrase;
  17. import com.itextpdf.text.pdf.ColumnText;
  18. import com.itextpdf.text.pdf.PdfAction;
  19. import com.itextpdf.text.pdf.PdfAnnotation;
  20. import com.itextpdf.text.pdf.PdfCopy;
  21. import com.itextpdf.text.pdf.PdfCopy.PageStamp;
  22. import com.itextpdf.text.pdf.PdfImportedPage;
  23. import com.itextpdf.text.pdf.PdfReader;
  24. import com.itextpdf.text.pdf.draw.DottedLineSeparator;
  25.  
  26. import java.io.File;
  27. import java.io.FileOutputStream;
  28. import java.io.IOException;
  29. import java.util.Map;
  30. import java.util.TreeMap;
  31.  
  32. import sandbox.WrapToTest;
  33.  
  34. @WrapToTest
  35. public class MergeWithToc {
  36.  
  37.     public static final String SRC1 = "resources/pdfs/united_states.pdf";
  38.     public static final String SRC2 = "resources/pdfs/hello.pdf";
  39.     public static final String SRC3 = "resources/pdfs/toc.pdf";
  40.     public static final String DEST = "results/merge/merge_with_toc.pdf";
  41.    
  42.     public Map filesToMerge;
  43.    
  44.     public static void main(String[] args) throws IOException, DocumentException {
  45.         File file = new File(DEST);
  46.         file.getParentFile().mkdirs();
  47.         MergeWithToc app = new MergeWithToc();
  48.         app.createPdf(DEST);
  49.     }
  50.    
  51.     public MergeWithToc() throws IOException {
  52.         filesToMerge = new TreeMap();
  53.         filesToMerge.put("01 Hello World", new PdfReader(SRC1));
  54.         filesToMerge.put("02 Movies / Countries", new PdfReader(SRC2));
  55.     }
  56.    
  57.     public void createPdf(String filename) throws IOException, DocumentException {
  58.         Map toc = new TreeMap();
  59.         Document document = new Document();
  60.         PdfCopy copy = new PdfCopy(document, new FileOutputStream(filename));
  61.         PageStamp stamp;
  62.         document.open();
  63.         int n;
  64.         int pageNo = 0;
  65.         PdfImportedPage page;
  66.         Chunk chunk;
  67.         for (Map.Entry entry : filesToMerge.entrySet()) {
  68.             n = entry.getValue().getNumberOfPages();
  69.             toc.put(pageNo + 1, entry.getKey());
  70.             for (int i = 0; i < n; ) {
  71.                 pageNo++;
  72.                 page = copy.getImportedPage(entry.getValue(), ++i);
  73.                 stamp = copy.createPageStamp(page);
  74.                 chunk = new Chunk(String.format("Page %d", pageNo));
  75.                 if (i == 1)
  76.                     chunk.setLocalDestination("p" + pageNo);
  77.                 ColumnText.showTextAligned(stamp.getUnderContent(),
  78.                         Element.ALIGN_RIGHT, new Phrase(chunk),
  79.                         559, 810, 0);
  80.                 stamp.alterContents();
  81.                 copy.addPage(page);
  82.             }
  83.         }
  84.         PdfReader reader = new PdfReader(SRC3);
  85.         page = copy.getImportedPage(reader, 1);
  86.         stamp = copy.createPageStamp(page);
  87.         Paragraph p;
  88.         PdfAction action;
  89.         PdfAnnotation link;
  90.         float y = 770;
  91.         ColumnText ct = new ColumnText(stamp.getOverContent());
  92.         ct.setSimpleColumn(36, 36, 559, y);
  93.         for (Map.Entry entry : toc.entrySet()) {
  94.             p = new Paragraph(entry.getValue());
  95.             p.add(new Chunk(new DottedLineSeparator()));
  96.             p.add(String.valueOf(entry.getKey()));
  97.             ct.addElement(p);
  98.             ct.go();
  99.             action = PdfAction.gotoLocalPage("p" + entry.getKey(), false);
  100.             link = new PdfAnnotation(copy, 36, ct.getYLine(), 559, y, action);
  101.             stamp.addAnnotation(link);
  102.             y = ct.getYLine();
  103.         }
  104.         ct.go();
  105.         stamp.alterContents();
  106.         copy.addPage(page);
  107.         document.close();
  108.         for (PdfReader r : filesToMerge.values()) {
  109.             r.close();
  110.         }
  111.         reader.close();
  112.     }
  113. }
MergeWithToc2.java
  1. /**
  2.  * Example written by Bruno Lowagie in answer to:
  3.  * http://stackoverflow.com/questions/21548552/create-index-filetoc-for-merged-pdf-using-itext-library-in-java
  4.  *
  5.  * When concatenating documents, we add a named destination every time
  6.  * a new document is started. After we've finished merging, we add an extra
  7.  * page with the table of contents and links to the named destinations.
  8.  */
  9. package sandbox.merge;
  10.  
  11. import com.itextpdf.text.Chunk;
  12. import com.itextpdf.text.Document;
  13. import com.itextpdf.text.DocumentException;
  14. import com.itextpdf.text.Element;
  15. import com.itextpdf.text.Paragraph;
  16. import com.itextpdf.text.Phrase;
  17. import com.itextpdf.text.pdf.ColumnText;
  18. import com.itextpdf.text.pdf.PdfAction;
  19. import com.itextpdf.text.pdf.PdfAnnotation;
  20. import com.itextpdf.text.pdf.PdfCopy;
  21. import com.itextpdf.text.pdf.PdfCopy.PageStamp;
  22. import com.itextpdf.text.pdf.PdfImportedPage;
  23. import com.itextpdf.text.pdf.PdfReader;
  24. import com.itextpdf.text.pdf.PdfStamper;
  25. import com.itextpdf.text.pdf.draw.DottedLineSeparator;
  26.  
  27. import java.io.ByteArrayOutputStream;
  28. import java.io.File;
  29. import java.io.FileOutputStream;
  30. import java.io.IOException;
  31. import java.util.Map;
  32. import java.util.TreeMap;
  33.  
  34. import sandbox.WrapToTest;
  35.  
  36. @WrapToTest
  37. public class MergeWithToc2 {
  38.  
  39.     public static final String SRC1 = "resources/pdfs/united_states.pdf";
  40.     public static final String SRC2 = "resources/pdfs/hello.pdf";
  41.     public static final String SRC3 = "resources/pdfs/toc.pdf";
  42.     public static final String DEST = "results/merge/merge_with_toc2.pdf";
  43.    
  44.     public Map filesToMerge;
  45.    
  46.     public static void main(String[] args) throws IOException, DocumentException {
  47.         File file = new File(DEST);
  48.         file.getParentFile().mkdirs();
  49.         MergeWithToc2 app = new MergeWithToc2();
  50.         app.createPdf(DEST);
  51.     }
  52.    
  53.     public MergeWithToc2() throws IOException {
  54.         filesToMerge = new TreeMap();
  55.         filesToMerge.put("01 Hello World", new PdfReader(SRC1));
  56.         filesToMerge.put("02 Movies / Countries", new PdfReader(SRC2));
  57.     }
  58.    
  59.     public void createPdf(String filename) throws IOException, DocumentException {
  60.         ByteArrayOutputStream baos = new ByteArrayOutputStream();
  61.         Map toc = new TreeMap();
  62.         Document document = new Document();
  63.         PdfCopy copy = new PdfCopy(document, baos);
  64.         PageStamp stamp;
  65.         document.open();
  66.         int n;
  67.         int pageNo = 0;
  68.         PdfImportedPage page;
  69.         Chunk chunk;
  70.         for (Map.Entry entry : filesToMerge.entrySet()) {
  71.             n = entry.getValue().getNumberOfPages();
  72.             toc.put(pageNo + 1, entry.getKey());
  73.             for (int i = 0; i < n; ) {
  74.                 pageNo++;
  75.                 page = copy.getImportedPage(entry.getValue(), ++i);
  76.                 stamp = copy.createPageStamp(page);
  77.                 chunk = new Chunk(String.format("Page %d", pageNo));
  78.                 if (i == 1)
  79.                     chunk.setLocalDestination("p" + pageNo);
  80.                 ColumnText.showTextAligned(stamp.getUnderContent(),
  81.                         Element.ALIGN_RIGHT, new Phrase(chunk),
  82.                         559, 810, 0);
  83.                 stamp.alterContents();
  84.                 copy.addPage(page);
  85.             }
  86.         }
  87.         PdfReader reader = new PdfReader(SRC3);
  88.         page = copy.getImportedPage(reader, 1);
  89.         stamp = copy.createPageStamp(page);
  90.         Paragraph p;
  91.         PdfAction action;
  92.         PdfAnnotation link;
  93.         float y = 770;
  94.         ColumnText ct = new ColumnText(stamp.getOverContent());
  95.         ct.setSimpleColumn(36, 36, 559, y);
  96.         for (Map.Entry entry : toc.entrySet()) {
  97.             p = new Paragraph(entry.getValue());
  98.             p.add(new Chunk(new DottedLineSeparator()));
  99.             p.add(String.valueOf(entry.getKey()));
  100.             ct.addElement(p);
  101.             ct.go();
  102.             action = PdfAction.gotoLocalPage("p" + entry.getKey(), false);
  103.             link = new PdfAnnotation(copy, 36, ct.getYLine(), 559, y, action);
  104.             stamp.addAnnotation(link);
  105.             y = ct.getYLine();
  106.         }
  107.         ct.go();
  108.         stamp.alterContents();
  109.         copy.addPage(page);
  110.         document.close();
  111.         for (PdfReader r : filesToMerge.values()) {
  112.             r.close();
  113.         }
  114.         reader.close();
  115.        
  116.         reader = new PdfReader(baos.toByteArray());
  117.         n = reader.getNumberOfPages();
  118.         reader.selectPages(String.format("%d, 1-%d", n, n-1));
  119.         PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(filename));
  120.         stamper.close();
  121.     }
  122. }
Contact

Still have questions? 

We're happy to answer your questions. Reach out to us and we'll get back to you shortly.

Contact us
Stay updated

Join 11,000+ subscribers and become an iText PDF expert by staying up to date with our new products, updates, tips, technical solutions and happenings.

Subscribe Now