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

Requirements
View Demo

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.

Implementation steps

To manipulate bookmarks and outlines with Apryse Server SDK:

Step 1: Follow get started with Server SDK in your preferred language or framework
Step 2: Add the sample code provided in this guide

To use this feature in production, your license key will need the Page Manipulation Package. Trial keys already include all packages.

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