Scheduled Maintenance
-
February 10, 2026, from 8:00 AM to 9:00 AM PST. Account-related operations might be temporarily unavailable.

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
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