Flatten Form Showcase Demo Code Sample

Requirements
View Demo

Easily enable annotation and form flattening capabilities to permanently merge annotations with page content.

This demo allows you to:

  • Annotate a PDF
  • Edit fields
  • Merge fields and annotations into the page content
  • Download the updated PDF

Implementation steps

To add annotation and form flattening capabilities to WebViewer:
Step 1: Get stared in your preferred web stack for WebViewer
Step 2: Add the ES6 JavaScript sample code provided in this guide

Once you generate your license key, it will automatically be included in your sample code below.

License Key

1// ES6 Compliant Syntax
2// GitHub Copilot v1.0 - GPT-4 Model - July 15, 2025
3// File: index.js
4
5import WebViewer from '@pdftron/webviewer';
6
7const licenseKey = 'YOUR_WEBVIEWER_LICENSE_KEY';
8
9// Customize the WebViewer UI
10// Add custom buttons for flattening forms and downloading PDFs
11const customizeUI = (instance) => {
12 const { UI } = instance;
13
14 // Flattening button
15 const flattenButton = new UI.Components.CustomButton({
16 dataElement: 'flattenButton',
17 className: 'custom-button-class',
18 label: 'Flattening',
19 onClick: () => flatten(instance), // Flatten the document
20 style: {
21 padding: '10px 20px',
22 backgroundColor: 'white',
23 color: 'blue',
24 border: '1px solid blue',
25 }
26 });
27
28 // Download button
29 const downloadButton = new UI.Components.CustomButton({
30 dataElement: 'downloadPdfButton',
31 className: 'custom-button-class',
32 label: 'Download',
33 onClick: () => download(instance), // Download with annotations
34 style: {
35 padding: '10px 20px',
36 backgroundColor: 'blue',
37 color: 'white',
38 }
39 });
40
41 const defaultHeader = UI.getModularHeader('default-top-header');
42 defaultHeader.setItems([...defaultHeader.items, flattenButton, downloadButton]);
43};
44
45// Flatten the form fields in the PDF document
46const flatten = async (instance) => {
47 const { documentViewer, PDFNet, annotationManager } = instance.Core;
48
49 await PDFNet.initialize();
50 const doc = await documentViewer.getDocument().getPDFDoc();
51 const annotations = await annotationManager.exportAnnotations();
52
53 // Run PDFNet methods with memory management
54 await PDFNet.runWithCleanup(async () => {
55
56 // lock the document before a write operation
57 // runWithCleanup will auto unlock when complete
58 doc.lock();
59
60 // import annotations to PDFNet
61 const fdf_doc = await PDFNet.FDFDoc.createFromXFDF(annotations);
62 await doc.fdfUpdate(fdf_doc);
63
64 // Generate appearances in a way that supports non-standard rotation
65 const options = await PDFNet.PDFDoc.createRefreshOptions();
66 options.setUseNonStandardRotation(true);
67 await doc.refreshAnnotAppearances(options);
68
69 // flatten all annotations in the document
70 await doc.flattenAnnotations();
71
72 // clear the original annotations
73 annotationManager.deleteAnnotations(annotationManager.getAnnotationsList());
74 });
75
76 // clear the cache (rendered) data with the newly updated document
77 documentViewer.refreshAll();
78
79 // Update viewer to render with the new document
80 documentViewer.updateView();
81
82 // Refresh searchable and selectable text data with the new document
83 documentViewer.getDocument().refreshTextData();
84};
85
86// Download the PDF
87const download = async (instance) => {
88
89 // Set the options for downloading the PDF
90 const options = {
91 flags: instance.Core.SaveOptions.LINEARIZED,
92 downloadType: 'pdf'
93 };
94
95 instance.UI.downloadPdf(options);
96};
97
98WebViewer(
99 {
100 path: '/lib',
101 initialDoc: 'https://apryse.s3.us-west-1.amazonaws.com/public/files/samples/form.pdf',
102 fullAPI: true,
103 enableFilePicker: true, // Enable file picker to open files. In WebViewer -> menu icon -> Open File
104 licenseKey: licenseKey,
105 },
106 document.getElementById('viewer')
107).then((instance) => {
108
109 // customize WebViewer UI
110 customizeUI(instance);
111
112 console.log('✅ WebViewer loaded successfully.');
113}).catch((error) => {
114 console.error('❌ Failed to initialize WebViewer:', error);
115});

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales
Flatten PDF Form - Sample Code - JavaScript using WebViewer | Apryse documentation