PDF Bookmarks and Outlines - Add/Edit/Read - Java Sample Code

Sample code to use Apryse SDK for programmatically reading and editing existing outline items, and for creating new PDF bookmarks using the high-level API. Sample code provided in Python, C++, C#, Java, Node.js (JavaScript), PHP, Ruby and VB.

Learn more about our Server SDK and PDF Editing & Manipulation Library.

1//---------------------------------------------------------------------------------------
2// Copyright (c) 2001-2024 by Apryse Software Inc. All Rights Reserved.
3// Consult legal.txt regarding legal and license information.
4//---------------------------------------------------------------------------------------
5
6import com.pdftron.common.PDFNetException;
7import com.pdftron.pdf.*;
8import com.pdftron.sdf.Obj;
9import com.pdftron.sdf.SDFDoc;
10
11
12public class BookmarkTest {
13
14 public static void main(String[] args) {
15 PDFNet.initialize(PDFTronLicense.Key());
16
17 // Relative path to the folder containing test files.
18 String input_path = "../../TestFiles/";
19 String output_path = "../../TestFiles/Output/";
20
21 // The following example illustrates how to create and edit the outline tree
22 // using high-level Bookmark methods.
23 try (PDFDoc doc = new PDFDoc((input_path + "numbered.pdf"))) {
24 doc.initSecurityHandler();
25
26 // Lets first create the root bookmark items.
27 Bookmark red = Bookmark.create(doc, "Red");
28 Bookmark green = Bookmark.create(doc, "Green");
29 Bookmark blue = Bookmark.create(doc, "Blue");
30
31 doc.addRootBookmark(red);
32 doc.addRootBookmark(green);
33 doc.addRootBookmark(blue);
34
35 // You can also add new root bookmarks using Bookmark.AddNext("...")
36 blue.addNext("foo");
37 blue.addNext("bar");
38
39 // We can now associate new bookmarks with page destinations:
40
41 // The following example creates an 'explicit' destination (see
42 // section '8.2.1 Destinations' in PDF Reference for more details)
43 Destination red_dest = Destination.createFit(doc.getPageIterator().next());
44 red.setAction(Action.createGoto(red_dest));
45
46 // Create an explicit destination to the first green page in the document
47 green.setAction(Action.createGoto(
48 Destination.createFit(doc.getPage(10))));
49
50 // The following example creates a 'named' destination (see
51 // section '8.2.1 Destinations' in PDF Reference for more details)
52 // Named destinations have certain advantages over explicit destinations.
53 byte[] key = {'b', 'l', 'u', 'e', '1'};
54 Action blue_action = Action.createGoto(key,
55 Destination.createFit(doc.getPage(19)));
56
57 blue.setAction(blue_action);
58
59 // We can now add children Bookmarks
60 Bookmark sub_red1 = red.addChild("Red - Page 1");
61 sub_red1.setAction(Action.createGoto(Destination.createFit(doc.getPage(1))));
62 Bookmark sub_red2 = red.addChild("Red - Page 2");
63 sub_red2.setAction(Action.createGoto(Destination.createFit(doc.getPage(2))));
64 Bookmark sub_red3 = red.addChild("Red - Page 3");
65 sub_red3.setAction(Action.createGoto(Destination.createFit(doc.getPage(3))));
66 Bookmark sub_red4 = sub_red3.addChild("Red - Page 4");
67 sub_red4.setAction(Action.createGoto(Destination.createFit(doc.getPage(4))));
68 Bookmark sub_red5 = sub_red3.addChild("Red - Page 5");
69 sub_red5.setAction(Action.createGoto(Destination.createFit(doc.getPage(5))));
70 Bookmark sub_red6 = sub_red3.addChild("Red - Page 6");
71 sub_red6.setAction(Action.createGoto(Destination.createFit(doc.getPage(6))));
72
73 // Example of how to find and delete a bookmark by title text.
74 Bookmark foo = doc.getFirstBookmark().find("foo");
75 if (foo.isValid()) {
76 foo.delete();
77 } else {
78 throw new Exception("Foo is not Valid");
79 }
80
81 Bookmark bar = doc.getFirstBookmark().find("bar");
82 if (bar.isValid()) {
83 bar.delete();
84 } else {
85 throw new Exception("Bar is not Valid");
86 }
87
88 // Adding color to Bookmarks. Color and other formatting can help readers
89 // get around more easily in large PDF documents.
90 red.setColor(1, 0, 0);
91 green.setColor(0, 1, 0);
92 green.setFlags(2); // set bold font
93 blue.setColor(0, 0, 1);
94 blue.setFlags(3); // set bold and itallic
95
96 doc.save((output_path + "bookmark.pdf"), SDFDoc.SaveMode.NO_FLAGS, null);
97 System.out.println("Done. Result saved in bookmark.pdf");
98 } catch (Exception e) {
99 System.out.println(e);
100 }
101
102 // The following example illustrates how to traverse the outline tree using
103 // Bookmark navigation methods: Bookmark.GetNext(), Bookmark.GetPrev(),
104 // Bookmark.GetFirstChild () and Bookmark.GetLastChild ().
105 // Open the document that was saved in the previous code sample
106 try (PDFDoc doc = new PDFDoc((output_path + "bookmark.pdf"))) {
107 doc.initSecurityHandler();
108
109 Bookmark root = doc.getFirstBookmark();
110 PrintOutlineTree(root);
111 System.out.println("Done.");
112 } catch (Exception e) {
113 System.out.println(e);
114 }
115
116 // The following example illustrates how to create a Bookmark to a page
117 // in a remote document. A remote go-to action is similar to an ordinary
118 // go-to action, but jumps to a destination in another PDF file instead
119 // of the current file. See Section 8.5.3 'Remote Go-To Actions' in PDF
120 // Reference Manual for details.
121 // Open the document that was saved in the previous code sample
122 try (PDFDoc doc = new PDFDoc((output_path + "bookmark.pdf"))) {
123 doc.initSecurityHandler();
124
125 // Create file specification (the file reffered to by the remote bookmark)
126 Obj file_spec = doc.createIndirectDict();
127 file_spec.putName("Type", "Filespec");
128 file_spec.putString("F", "bookmark.pdf");
129 FileSpec spec = new FileSpec(file_spec);
130 Action goto_remote = Action.createGotoRemote(spec, 5, true);
131
132 Bookmark remoteBookmark1 = Bookmark.create(doc, "REMOTE BOOKMARK 1");
133 remoteBookmark1.setAction(goto_remote);
134 doc.addRootBookmark(remoteBookmark1);
135
136 // Create another remote bootmark, but this time using the low-level SDF/Cos API.
137 // Create a remote action
138 Bookmark remoteBookmark2 = Bookmark.create(doc, "REMOTE BOOKMARK 2");
139 doc.addRootBookmark(remoteBookmark2);
140
141 Obj gotoR = remoteBookmark2.getSDFObj().putDict("A");
142 {
143 gotoR.putName("S", "GoToR"); // Set action type
144 gotoR.putBool("NewWindow", true);
145
146 // Set the file specification
147 gotoR.put("F", file_spec);
148
149 // jump to the first page. Note that pages are indexed from 0.
150 Obj dest = gotoR.putArray("D"); // Set the destination
151 dest.pushBackNumber(9);
152 dest.pushBackName("Fit");
153 }
154
155 doc.save((output_path + "bookmark_remote.pdf"), SDFDoc.SaveMode.LINEARIZED, null);
156 System.out.println("Done. Result saved in bookmark_remote.pdf");
157 } catch (Exception e) {
158 System.out.println(e);
159 }
160
161 PDFNet.terminate();
162 }
163
164 static void PrintIndent(Bookmark item) throws PDFNetException {
165 int ident = item.getIndent() - 1;
166 for (int i = 0; i < ident; ++i) System.out.print(" ");
167 }
168
169 // Prints out the outline tree to the standard output
170 static void PrintOutlineTree(Bookmark item) throws PDFNetException {
171 for (; item.isValid(); item = item.getNext()) {
172 PrintIndent(item);
173 System.out.print((item.isOpen() ? "- " : "+ ") + item.getTitle() + " ACTION -> ");
174
175 // Print Action
176 Action action = item.getAction();
177 if (action.isValid()) {
178 if (action.getType() == Action.e_GoTo) {
179 Destination dest = action.getDest();
180 if (dest.isValid()) {
181 Page page = dest.getPage();
182 System.out.println("GoTo Page #" + page.getIndex());
183 }
184 } else {
185 System.out.println("Not a 'GoTo' action");
186 }
187 } else {
188 System.out.println("NULL");
189 }
190
191 if (item.hasChildren()) // Recursively print children sub-trees
192 {
193 PrintOutlineTree(item.getFirstChild());
194 }
195 }
196 }
197}

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales