iText pdf library
Website search

Creating Table of Contents using events

Example written in answer to the question How can I add titles of chapters in ColumnText?

CreateTOCinColumn.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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
    This file is part of the iText (R) project.
    Copyright (c) 1998-2019 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:
 * http://stackoverflow.com/questions/29092738/itext-chapter-title-and-columntext
 */
 
package com.itextpdf.samples.sandbox.events;
 
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfOutline;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.navigation.PdfDestination;
import com.itextpdf.kernel.pdf.navigation.PdfExplicitDestination;
import com.itextpdf.layout.ColumnDocumentRenderer;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.AreaBreak;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Link;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.element.Text;
import com.itextpdf.layout.property.UnitValue;
import com.itextpdf.layout.renderer.DrawContext;
import com.itextpdf.layout.renderer.IRenderer;
import com.itextpdf.layout.renderer.TextRenderer;
 
import java.io.File;
import java.util.ArrayList;
import java.util.List;
 
public class CreateTOCinColumn {
    public static final String DEST = "./target/sandbox/events/create_toc_in_column.pdf";
 
    protected List<TOCEntry> list = new ArrayList<>();
 
    public static void main(String[] args) throws Exception {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
 
        new CreateTOCinColumn().manipulatePdf(DEST);
    }
 
    protected void manipulatePdf(String dest) throws Exception {
        PdfDocument pdfDoc = new PdfDocument(new PdfWriter(DEST));
        Document doc = new Document(pdfDoc);
        Rectangle[] columns = {
                new Rectangle(36, 36, 173, 770),
                new Rectangle(213, 36, 173, 770),
                new Rectangle(389, 36, 173, 770)
        };
        doc.setRenderer(new ColumnDocumentRenderer(doc, columns));
        PdfOutline root = pdfDoc.getOutlines(false);
        int start;
        int end;
        for (int i = 0; i <= 20; ) {
            start = (i * 10) + 1;
            i++;
            end = i * 10;
            String title = String.format("Numbers from %s to %s", start, end);
            Text c = new Text(title);
            TOCTextRenderer renderer = new TOCTextRenderer(c);
            renderer.setRoot(root);
            c.setNextRenderer(renderer);
            doc.add(new Paragraph(c));
            doc.add(createTable(start, end));
        }
        doc.add(new AreaBreak());
        for (TOCEntry entry : list) {
            Link c = new Link(entry.title, entry.dest);
            doc.add(new Paragraph(c));
        }
        doc.close();
    }
 
    protected Table createTable(int start, int end) {
        Table table = new Table(UnitValue.createPercentArray(2)).useAllAvailableWidth();
        for (int i = start; i <= end; i++) {
            table.addCell(new Cell().add(new Paragraph(String.valueOf(i))));
            table.addCell(new Cell().add(new Paragraph("Test")));
        }
        return table;
    }
 
 
    protected class TOCEntry {
        protected String title;
        protected PdfDestination dest;
 
        public TOCEntry(String title, PdfDestination dest) {
            this.dest = dest;
            this.title = title;
        }
    }
 
 
    protected class TOCTextRenderer extends TextRenderer {
        protected PdfOutline root;
 
        public TOCTextRenderer(Text modelElement) {
            super(modelElement);
        }
 
        public void setRoot(PdfOutline root) {
            this.root = root;
        }
 
        // If renderer overflows on the next area, iText uses getNextRender() method to create a renderer for the overflow part.
        // If getNextRenderer isn't overriden, the default method will be used and thus a default rather than custom
        // renderer will be created
        @Override
        public IRenderer getNextRenderer() {
            return new TOCTextRenderer((Text) modelElement);
        }
 
        @Override
        public void draw(DrawContext drawContext) {
            super.draw(drawContext);
            Rectangle rect = getOccupiedAreaBBox();
            PdfDestination dest = PdfExplicitDestination.createXYZ(drawContext.getDocument().getLastPage(),
                    rect.getLeft(), rect.getTop(), 0);
            list.add(new TOCEntry(((Text) modelElement).getText(), dest));
 
            PdfOutline curOutline = root.addOutline(((Text) modelElement).getText());
            curOutline.addDestination(dest);
        }
    }
}

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