Sample JavaScript code to use Apryse SDK for programmatically reading and editing existing outline items, and for creating new PDF bookmarks using the high-level API.
This sample is utilizing the option to run code programmatically, without the Viewer.
Learn more about our Web SDK and Outline & Bookmarks Library.
To manipulate outlines & bookmarks in PDF with WebViewer:
Step 1: Follow get started in your preferred web stack for WebViewer
Step 2: Follow set up to implement Full API code without viewer
Step 3: Add the sample code provided in this guide
This full sample is included in the manual download of WebViewer.
1//---------------------------------------------------------------------------------------
2// Copyright (c) 2001-2023 by Apryse Software Inc. All Rights Reserved.
3// Consult legal.txt regarding legal and license information.
4//---------------------------------------------------------------------------------------
5
6(exports => {
7 exports.runBookmarkTest = () => {
8 const PDFNet = exports.Core.PDFNet;
9
10 const addIndent = async (item, str) => {
11 const ident = (await item.getIndent()) - 1;
12 for (let i = 0; i < ident; ++i) {
13 str += ' ';
14 // note: must manually set IndentString to empty after this function is called.
15 }
16 return str;
17 };
18
19 const printOutlineTree = async item => {
20 for (; item != null; item = await item.getNext()) {
21 let IndentString = '';
22 let ActionString = '';
23 let TitleString = '';
24
25 IndentString = await addIndent(item, IndentString);
26 TitleString = await item.getTitle();
27
28 ActionString = (IndentString + (await item.isOpen()) ? '- ' : '+ ') + TitleString + ' ACTION -> ';
29
30 const action = await item.getAction();
31 if (await action.isValid()) {
32 const actionType = await action.getType();
33 if (actionType === PDFNet.Action.Type.e_GoTo) {
34 const dest = await action.getDest();
35 if (await dest.isValid()) {
36 const page = await dest.getPage();
37 console.log(ActionString + 'GoTo Page # ' + (await page.getIndex()));
38 }
39 } else {
40 console.log(ActionString + 'Not a "GoTo" action');
41 }
42 } else {
43 console.log(ActionString + 'NULL');
44 }
45
46 if (await item.hasChildren()) {
47 await printOutlineTree(await item.getFirstChild());
48 }
49 }
50 };
51
52 const main = async () => {
53 const ret = 0;
54
55 // Relative path to the folder containing test files.
56 const inputPath = '../TestFiles/';
57
58 // The following example illustrates how to create and edit the outline tree
59 // using high-level Bookmark methods.
60
61 let doc = await PDFNet.PDFDoc.createFromURL(inputPath + 'numbered.pdf');
62 doc.initSecurityHandler();
63 doc.lock();
64
65 // Lets first create the root bookmark items.
66 const red = await PDFNet.Bookmark.create(doc, 'Red');
67 const green = await PDFNet.Bookmark.create(doc, 'Green');
68 const blue = await PDFNet.Bookmark.create(doc, 'Blue');
69
70 doc.addRootBookmark(red);
71 doc.addRootBookmark(green);
72 doc.addRootBookmark(blue);
73
74 // You can also add new root bookmarks using Bookmark.addNext("...")
75 blue.addNewNext('foo');
76 blue.addNewNext('bar');
77
78 // We can now associate new bookmarks with page destinations:
79
80 // The following example creates an 'explicit' destination (see
81 // section '8.2.1 Destinations' in PDF Reference for more details)
82
83 const redIter = await doc.getPageIterator(1);
84
85 const redCurrpage = await redIter.current();
86 // eslint-disable-next-line @typescript-eslint/no-unused-vars
87 const redCurrpageActual = await doc.getPage(1);
88 const redDest = await PDFNet.Destination.createFit(redCurrpage);
89 red.setAction(await PDFNet.Action.createGoto(redDest));
90
91 // Create an explicit destination to the first green page in the document
92 const tenthPage = await doc.getPage(10);
93 const greenDest = await PDFNet.Destination.createFit(tenthPage);
94 green.setAction(await PDFNet.Action.createGoto(greenDest));
95
96 // The following example creates a 'named' destination (see
97 // section '8.2.1 Destinations' in PDF Reference for more details)
98 // Named destinations have certain advantages over explicit destinations.
99 const key = 'blue1';
100 const nineteenthPage = await doc.getPage(19);
101 const blueDest = await PDFNet.Destination.createFit(nineteenthPage);
102 const blueAction = await PDFNet.Action.createGotoWithKey(key, blueDest); // TODO FIND FIX
103
104 blue.setAction(blueAction);
105
106 // We can now add children Bookmarks subRed1 instanceof Promise
107 const subRed1 = await red.addNewChild('Red - Page 1');
108 subRed1.setAction(await PDFNet.Action.createGoto(await PDFNet.Destination.createFit(await doc.getPage(1))));
109 const subRed2 = await red.addNewChild('Red - Page 2');
110 subRed2.setAction(await PDFNet.Action.createGoto(await PDFNet.Destination.createFit(await doc.getPage(2))));
111 const subRed3 = await red.addNewChild('Red - Page 3');
112 subRed3.setAction(await PDFNet.Action.createGoto(await PDFNet.Destination.createFit(await doc.getPage(3))));
113 const subRed4 = await subRed3.addNewChild('Red - Page 4');
114 subRed4.setAction(await PDFNet.Action.createGoto(await PDFNet.Destination.createFit(await doc.getPage(4))));
115 const subRed5 = await subRed3.addNewChild('Red - Page 5');
116 subRed5.setAction(await PDFNet.Action.createGoto(await PDFNet.Destination.createFit(await doc.getPage(5))));
117 const subRed6 = await subRed3.addNewChild('Red - Page 6');
118 subRed6.setAction(await PDFNet.Action.createGoto(await PDFNet.Destination.createFit(await doc.getPage(6))));
119
120 // Example of how to find and delete a bookmark by title text.
121 const firstbookmark = await doc.getFirstBookmark();
122 const foo = await firstbookmark.find('foo');
123 if (await foo.isValid()) {
124 foo.delete();
125 } else {
126 console.log('Bookmark foo is invalid');
127 }
128 const bar = await firstbookmark.find('bar');
129 if (await bar.isValid()) {
130 bar.delete();
131 } else {
132 console.log('Bookmark bar is invalid');
133 }
134
135 // Adding color to Bookmarks. Color and other formatting can help readers
136 // get around more easily in large PDF documents.
137 red.setColor(1, 0, 0);
138 green.setColor(0, 1, 0);
139 green.setFlags(2); // set bold font
140 blue.setColor(0, 0, 1);
141 blue.setFlags(3); // set bold and italic
142
143 const bookmarkBuffer = await doc.saveMemoryBuffer(0);
144 saveBufferAsPDFDoc(bookmarkBuffer, 'bookmark.pdf');
145 console.log('Done. Result saved in bookmark.pdf');
146
147 // The following example illustrates how to traverse the outline tree using
148 // Bookmark navigation methods: Bookmark.getNext(), Bookmark.getPrev(),
149 // Bookmark.getFirstChild () and Bookmark.getLastChild ().
150
151 // Open the document that was saved in the previous code sample
152 const docOut = await PDFNet.PDFDoc.createFromBuffer(bookmarkBuffer);
153 docOut.initSecurityHandler();
154 docOut.lock();
155
156 const root = await docOut.getFirstBookmark();
157 await printOutlineTree(root);
158
159 console.log('Done.');
160
161 // The following example illustrates how to create a Bookmark to a page
162 // in a remote document. A remote go-to action is similar to an ordinary
163 // go-to action, but jumps to a destination in another PDF file instead
164 // of the current file. See Section 8.5.3 'Remote Go-To Actions' in PDF
165 // Reference Manual for details.
166
167 // Use the document from the previous sample. The sample is done this way
168 // since we cannot guarantee that bookmarkBuffer is still valid since it
169 // may have been sent using transfers to the worker
170 doc = docOut;
171
172 doc.initSecurityHandler();
173
174 // Create file specification (the file referred to by the remote bookmark)
175 const fileSpec = await doc.createIndirectDict();
176 fileSpec.putName('Type', 'Filespec');
177 fileSpec.putString('F', 'bookmark.pdf');
178 const spec = await PDFNet.FileSpec.createFromObj(fileSpec);
179 const gotoRemote = await PDFNet.Action.createGotoRemoteSetNewWindow(spec, 5, true);
180
181 const remoteBookmark1 = await PDFNet.Bookmark.create(doc, 'REMOTE BOOKMARK 1');
182 remoteBookmark1.setAction(gotoRemote);
183 doc.addRootBookmark(remoteBookmark1);
184
185 // Create another remote bookmark, but this time using the low-level SDF/Cos API.
186 // Create a remote action
187 const remoteBookmark2 = await PDFNet.Bookmark.create(doc, 'REMOTE BOOKMARK 2');
188 doc.addRootBookmark(remoteBookmark2);
189
190 const gotoR = await (await remoteBookmark2.getSDFObj()).putDict('A');
191 {
192 gotoR.putName('S', 'GoToR'); // Set action type
193 gotoR.putBool('NewWindow', true);
194
195 // Set the file specification
196 gotoR.put('F', fileSpec);
197
198 // jump to the first page. Note that pages are indexed from 0.
199 const dest = await gotoR.putArray('D');
200 dest.pushBackNumber(9);
201 dest.pushBackName('Fit');
202 }
203
204 const docbuf = await doc.saveMemoryBuffer(PDFNet.SDFDoc.SaveOptions.e_remove_unused);
205 saveBufferAsPDFDoc(docbuf, 'bookmark_remote.pdf');
206
207 console.log('Done. Result saved in bookmark_remote.pdf');
208 return ret;
209 };
210 // add your own license key as the second parameter, e.g. PDFNet.runWithCleanup(main, 'YOUR_LICENSE_KEY')
211 PDFNet.runWithCleanup(main);
212 };
213})(window);
214// eslint-disable-next-line spaced-comment
215//# sourceURL=BookmarkTest.js
Did you find this helpful?
Trial setup questions?
Ask experts on DiscordNeed other help?
Contact SupportPricing or product questions?
Contact Sales