iText pdf library
Website search

Merging documents with bookmarks

This example was originally written in answer to the question How to merge PDFs and add bookmarks? for iText5. The code here is a direct port from the iText5 code. Merging documents while maintaining bookmarks in iText7 is done automatically when using the PdfMergerobject.

InsertAndAdaptOutlines.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/*
    This file is part of the iText (R) project.
    Copyright (c) 1998-2020 iText Group NV
    Authors: iText Software.
 
    For more information, please contact iText Software at this address:
    sales@itextpdf.com
 */
/**
 * Example written in answer to:
 * http://stackoverflow.com/questions/34381849
 */
package com.itextpdf.samples.sandbox.merge;
 
import com.itextpdf.forms.PdfPageFormCopier;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfOutline;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.navigation.PdfExplicitDestination;
 
import java.io.File;
import java.io.IOException;
 
public class InsertAndAdaptOutlines {
    public static final String DEST = "./target/sandbox/merge/insert_and_adapt_outlines.pdf";
 
    public static final String INSERT = "./src/test/resources/pdfs/hello.pdf";
    public static final String SRC = "./src/test/resources/pdfs/bookmarks.pdf";
 
    public static void main(String[] args) throws IOException {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
 
        new InsertAndAdaptOutlines().manipulatePdf(DEST);
    }
 
    protected void manipulatePdf(String dest) throws IOException {
        PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(dest));
        int insertPageNumber = 4;
 
        // Copier contains the additional logic to copy acroform fields to a new page.
        // PdfPageFormCopier uses some caching logic which can potentially improve performance
        // in case of the reusing of the same instance.
        PdfPageFormCopier formCopier = new PdfPageFormCopier();
        PdfDocument insertDoc = new PdfDocument(new PdfReader(INSERT));
        insertDoc.copyPagesTo(1, 1, pdfDoc, insertPageNumber, formCopier);
        insertDoc.close();
 
        PdfOutline outlines = pdfDoc.getOutlines(false);
        PdfOutline outline = outlines.getAllChildren().get(0).addOutline("Hello", insertPageNumber - 1);
        outline.addDestination(PdfExplicitDestination.createFit(pdfDoc.getPage(insertPageNumber)));
 
        pdfDoc.close();
    }
}
MergeWithOutlines.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/*
    This file is part of the iText (R) project.
    Copyright (c) 1998-2020 iText Group NV
    Authors: iText Software.
 
    For more information, please contact iText Software at this address:
    sales@itextpdf.com
 */
/**
 * Example written by Bruno Lowagie in answer to a question on StackOverflow
 * <p>
 * When concatenating documents, we add a named destination every time
 * a new document is started. After we've finished merging, we add an extra
 * page with the table of contents and links to the named destinations.
 */
package com.itextpdf.samples.sandbox.merge;
 
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfOutline;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.navigation.PdfExplicitDestination;
import com.itextpdf.kernel.utils.PdfMerger;
 
import java.io.File;
import java.io.IOException;
 
public class MergeWithOutlines {
    public static final String DEST = "./target/sandbox/merge/merge_with_outlines.pdf";
 
    public static final String SRC1 = "./src/test/resources/pdfs/hello.pdf";
    public static final String SRC2 = "./src/test/resources/pdfs/links1.pdf";
    public static final String SRC3 = "./src/test/resources/pdfs/links2.pdf";
 
    public static void main(String[] args) throws IOException {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
 
        new MergeWithOutlines().manipulatePdf(DEST);
    }
 
    protected void manipulatePdf(String dest) throws IOException {
        PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
        PdfDocument srcDoc1 = new PdfDocument(new PdfReader(SRC1));
        PdfDocument srcDoc2 = new PdfDocument(new PdfReader(SRC2));
        PdfDocument srcDoc3 = new PdfDocument(new PdfReader(SRC3));
 
        int numberOfPages1 = srcDoc1.getNumberOfPages();
        int numberOfPages2 = srcDoc2.getNumberOfPages();
        int numberOfPages3 = srcDoc3.getNumberOfPages();
 
        PdfMerger merger = new PdfMerger(pdfDoc);
        merger.setCloseSourceDocuments(true)
                .merge(srcDoc1, 1, numberOfPages1)
                .merge(srcDoc2, 1, numberOfPages2)
                .merge(srcDoc3, 1, numberOfPages3);
 
        PdfOutline rootOutline = pdfDoc.getOutlines(false);
 
        int page = 1;
        PdfOutline helloWorld = rootOutline.addOutline("Hello World");
        helloWorld.addDestination(PdfExplicitDestination.createFit(pdfDoc.getPage(page)));
        page += numberOfPages1;
 
        PdfOutline link1 = helloWorld.addOutline("link1");
        link1.addDestination(PdfExplicitDestination.createFit(pdfDoc.getPage(page)));
        page += numberOfPages2;
 
        PdfOutline link2 = rootOutline.addOutline("Link 2");
        link2.addDestination(PdfExplicitDestination.createFit(pdfDoc.getPage(page)));
 
        pdfDoc.close();
    }
}

Click the following link to see the legacy example for iText 5. Except for security fixes, iText 5 is no longer being developed.



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