Flatten Form Showcase Demo Code Sample

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: Choose your preferred web stack
Step 2: Download any required modules listed in the Demo Dependencies section below
Step 3: Add the ES6 JavaScript sample code provided in this guide

Demo Dependencies
This sample uses the following:

Want to see a live version of this demo?

Try the Flatten Form demo

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

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales