Customize a PDF before Saving - Sample Code

Requirements

This JavaScript sample lets you customize or modify a PDF, DOCX, XLSX or PPTX document before it is saved/downloaded (client-side, no servers or other external dependencies required).

In this example annotations are flattened before saving the PDF. This functionality allows you to do a variety of modifications to the document before downloading – some common examples include adding stamps / watermarks to the PDF or injecting information into a document.

In the case of MS Office files, modifications are saved into the PDF file. The use of MS Office files will require the Office Conversion Package. (More WebViewer options: you could also manipulate DOCX or XSLX files directly with our DOCX Editor and Spreadsheet Editor.)

This sample works on all browsers (including IE11) and mobile devices without using plug-ins.

Learn more about our Web SDK.

Implementation steps

To customize and save PDF documents with JavaScript using WebViewer:

Step 1: Follow get started in your preferred web stack for WebViewer
Step 2: Enable the full API by passing the fullAPI option into the WebViewer constructor
Step 3: Add the sample code provided in this guide

This full sample is one of many included in the manual download of WebViewer.

1(exports => {
2 const PDFNet = exports.Core.PDFNet;
3 const mergeAndSave = (doc, xfdf) => {
4 const main = async () => {
5 // Import XFDF into FDF, then merge data from FDF into PDF
6 // Annotations
7 const fdfDoc = await PDFNet.FDFDoc.createFromXFDF(xfdf);
8
9 const pitr = await doc.getPageIterator();
10 let page;
11 let annotObj;
12 /* eslint no-await-in-loop: 0 */
13 for (; await pitr.hasNext(); pitr.next()) {
14 try {
15 page = await pitr.current();
16 for (let i = await page.getNumAnnots(); i > 0; ) {
17 annotObj = await page.getAnnot(--i);
18 switch (await annotObj.getType()) {
19 case PDFNet.Annot.Type.e_Widget:
20 case PDFNet.Annot.Type.e_Link:
21 case PDFNet.Annot.Type.e_Sound:
22 case PDFNet.Annot.Type.e_Movie:
23 case PDFNet.Annot.Type.e_FileAttachment:
24 // these are not supported for import from webviewer
25 break;
26 default:
27 page.annotRemoveByIndex(i);
28 break;
29 }
30 }
31 } catch (e) {
32 console.log('Error Removing Annotations: ' + e);
33 (await page.getSDFObj()).erase('Annots');
34 }
35 }
36
37 await doc.fdfMerge(fdfDoc);
38
39 // run any custom logic here
40 await doc.flattenAnnotations();
41
42 const docbuf = await doc.saveMemoryBuffer(PDFNet.SDFDoc.SaveOptions.e_linearized);
43 return docbuf;
44 };
45 // add your own license key as the second parameter, e.g. PDFNet.runWithCleanup(main, 'YOUR_LICENSE_KEY')
46 return PDFNet.runWithCleanup(main);
47 };
48
49 const customDownload = options => {
50 const documentViewer = instance.Core.documentViewer;
51 const am = documentViewer.getAnnotationManager();
52 const annotationsToRemove = am.getAnnotationsList();
53 const currentDocument = documentViewer.getDocument();
54 return PDFNet.initialize()
55 .then(() => currentDocument.getPDFDoc())
56 .then(pdfDoc => mergeAndSave(pdfDoc, options.xfdfString))
57 .then(data => {
58 // since we are flattening annotations we should remove the existing annotations in webviewer
59 // and rerender so that the file displays correctly
60
61 am.deleteAnnotations(annotationsToRemove);
62 // clear the cache
63 documentViewer.refreshAll();
64 // update viewer with new document
65 documentViewer.updateView();
66 // Annotations may contain text so we need to regenerate
67 // our text representation
68 documentViewer.getDocument().refreshTextData();
69 return data;
70 });
71 };
72
73 window.addEventListener('documentLoaded', () => {
74 const doc = instance.Core.documentViewer.getDocument();
75 doc.getFileData = customDownload;
76 });
77})(window);
78// eslint-disable-next-line spaced-comment
79//# sourceURL=config.js

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales