Skip to content

Commit 975f05c

Browse files
Merge pull request #2344 from syncfusion-content/1012852-reactUgDiatax
1012852: Updated flatten annotation UG
2 parents a7b6fd1 + b8e58c5 commit 975f05c

3 files changed

Lines changed: 268 additions & 0 deletions

File tree

Document-Processing-toc.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,6 +1086,7 @@
10861086
<li><a href="/document-processing/pdf/pdf-viewer/react/annotation/signature-annotation">Handwritten Signature</a></li>
10871087
<li><a href="/document-processing/pdf/pdf-viewer/react/annotation/line-angle-constraints">Line Angle Constraint</a></li>
10881088
<li><a href="/document-processing/pdf/pdf-viewer/react/annotation/custom-data">Adding custom Data in annotations</a></li>
1089+
<li><a href="/document-processing/pdf/pdf-viewer/react/annotation/flatten-annotation">Flatten Annotations into the PDF </a></li>
10891090
<li>Export and Import Annotations
10901091
<ul>
10911092
<li><a href="/document-processing/pdf/pdf-viewer/react/annotation/export-import/export-annotation">Export Annotation</a></li>
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
---
2+
layout: post
3+
title: Flatten Annotations in the Syncfusion React PDF Viewer
4+
description: Learn how all about how to flatten annotations and formfields before saving a PDF in the Syncfusion React PDF Viewer.
5+
platform: document-processing
6+
control: PDF Viewer
7+
documentation: ug
8+
domainurl: ##DomainURL##
9+
---
10+
11+
# Flatten Annotations in React PDF Viewer
12+
13+
Flattening takes the visual appearance of annotations and embeds them into each page's content stream. The visual result remains visible, but the annotation objects and interactive form field structures are removed or converted so they can no longer be selected, edited, or filled.
14+
15+
Flattening annotations permanently merges them into the PDF content. Once flattened:
16+
- Annotations are **no longer editable** in any PDF viewer.
17+
- Useful for **secure sharing**, preventing modifications.
18+
- Ideal when **finalizing markup** before distribution.
19+
20+
## How to Flatten Annotations
21+
22+
You can flatten annotations either when a document is loaded (preprocessing) or when exporting/saving the file. Flattening on load makes the viewer display a flattened version immediately; flattening on export preserves the original viewer session while producing a flattened output file.
23+
24+
Typical export-time steps:
25+
- Save the viewer contents to a Blob.
26+
- Create a `PdfDocument` from the saved bytes.
27+
- Enable `document.flatten = true` to merge annotations and form field appearances.
28+
- Save the resulting PDF.
29+
30+
Use the example below to flatten at export time (on download).
31+
32+
{% tabs %}
33+
{% highlight js tabtitle="Standalone" %}
34+
{% raw %}
35+
import { createRoot } from 'react-dom/client';
36+
import './index.css';
37+
import * as React from 'react';
38+
import {
39+
PdfViewerComponent,
40+
Toolbar,
41+
Magnification,
42+
Navigation,
43+
LinkAnnotation,
44+
BookmarkView,
45+
ThumbnailView,
46+
Print,
47+
TextSelection,
48+
TextSearch,
49+
Annotation,
50+
FormFields,
51+
FormDesigner,
52+
PageOrganizer,
53+
Inject,
54+
} from '@syncfusion/ej2-react-pdfviewer';
55+
import {
56+
PdfDocument
57+
} from '@syncfusion/ej2-pdf';
58+
59+
function Default() {
60+
let viewer;
61+
62+
const flattenPdf = () => {
63+
viewer.saveAsBlob().then((value) => {
64+
const reader = new FileReader();
65+
reader.onloadend = function () {
66+
const arrayBuffer = reader.result;
67+
const byteArray = new Uint8Array(arrayBuffer);
68+
const document = new PdfDocument(byteArray);
69+
// Flatten all annotations and form fields: this embeds appearances
70+
// into the page content so annotations are no longer interactive.
71+
document.flatten = true;
72+
document.save('flattened.pdf');
73+
};
74+
reader.readAsArrayBuffer(value);
75+
});
76+
};
77+
78+
return (
79+
<div>
80+
<div className="control-section">
81+
<button onClick={flattenPdf}>Flatten and download PDF</button>
82+
83+
<PdfViewerComponent
84+
ref={(scope) => { viewer = scope; }}
85+
id="container"
86+
documentPath="https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf"
87+
resourceUrl="https://cdn.syncfusion.com/ej2/23.2.6/dist/ej2-pdfviewer-lib"
88+
style={{ height: '640px' }}
89+
>
90+
<Inject
91+
services={[
92+
Toolbar,
93+
Magnification,
94+
Navigation,
95+
LinkAnnotation,
96+
BookmarkView,
97+
ThumbnailView,
98+
Print,
99+
TextSelection,
100+
TextSearch,
101+
Annotation,
102+
FormFields,
103+
FormDesigner,
104+
PageOrganizer,
105+
]}
106+
/>
107+
</PdfViewerComponent>
108+
</div>
109+
</div>
110+
);
111+
}
112+
export default Default;
113+
114+
const root = createRoot(document.getElementById('sample'));
115+
root.render(<Default />);
116+
{% endraw %}
117+
{% endhighlight %}
118+
{% endtabs %}
119+
120+
N> To flatten documents when they are uploaded/loaded into the viewer, see [Flatten on Load](../document-handling/preprocess-pdf#flatten-on-load).
121+
122+
123+
## Notes
124+
125+
- Flattening applies to **all annotation types**: text markup, shapes, stamps, notes, ink, and form fields.
126+
- Once flattened, annotations **cannot be edited or removed**.
127+
- Use flattening **only at export time**, not during regular document interactions.
128+
129+
## See also
130+
131+
- [Annotation Overview](../overview)
132+
- [Annotation Types](../annotation/annotation-types/area-annotation)
133+
- [Annotation Toolbar](../toolbar-customization/annotation-toolbar)
134+
- [Create and Modify Annotation](../annotation/create-modify-annotation)
135+
- [Customize Annotation](../annotation/customize-annotation)
136+
- [Handwritten Signature](../annotation/signature-annotation)
137+
- [Export and Import Annotation](../annotation/export-import/export-annotation)
138+
- [Annotation Permission](../annotation/annotation-permission)
139+
- [Annotation in Mobile View](../annotation/annotations-in-mobile-view)
140+
- [Annotation Events](../annotation/annotation-event)
141+
- [Annotation API](../annotation/annotations-api)

Document-Processing/PDF/PDF-Viewer/react/document-handling/preprocess-pdf.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,132 @@ doc.annotations.flattenAllAnnotations();
7373
const bytes = await doc.save();
7474
```
7575

76+
### Flatten on Load
77+
78+
Use the following code-snippet, when you want uploaded PDFs to be flattened before they are loaded into the viewer.
79+
80+
{% tabs %}
81+
{% highlight js tabtitle="Standalone" %}
82+
{% raw %}
83+
import { createRoot } from 'react-dom/client';
84+
import './index.css';
85+
import * as React from 'react';
86+
import {
87+
PdfViewerComponent,
88+
Toolbar,
89+
Annotation,
90+
FormFields,
91+
Inject,
92+
Magnification,
93+
} from '@syncfusion/ej2-react-pdfviewer';
94+
import { PdfDocument, _encode } from '@syncfusion/ej2-pdf';
95+
import { UploaderComponent } from '@syncfusion/ej2-react-inputs';
96+
function Default() {
97+
let viewer;
98+
const openFile = {
99+
prefixIcon: 'e-icons e-folder',
100+
id: 'openPdf',
101+
tooltipText: 'Open File',
102+
align: 'left',
103+
};
104+
const extensions = '.pdf';
105+
const toolbarSettings = {
106+
showTooltip: true,
107+
toolbarItems: [
108+
openFile,
109+
'PageNavigationTool',
110+
'MagnificationTool',
111+
'PanTool',
112+
'SelectionTool',
113+
'SearchOption',
114+
'PrintOption',
115+
'UndoRedoTool',
116+
'AnnotationEditTool',
117+
'FormDesignerEditTool',
118+
'CommentTool',
119+
'SubmitForm',
120+
'DownloadOption',
121+
],
122+
};
123+
124+
function toolbarClick(args) {
125+
if (args.item && args.item.id === 'openPdf') {
126+
document
127+
.getElementsByClassName('e-file-select-wrap')[0]
128+
.querySelector('button')
129+
.click();
130+
}
131+
}
132+
function onSelect(args) {
133+
let validFiles = args.filesData;
134+
if (validFiles.length === 0) {
135+
args.cancel = true;
136+
return;
137+
}
138+
if (!extensions.includes(validFiles[0].type)) {
139+
args.cancel = true;
140+
return;
141+
}
142+
143+
let file = validFiles[0].rawFile;
144+
let reader = new FileReader();
145+
146+
reader.addEventListener('load', () => {
147+
let base64Data = reader.result;
148+
let pdf = base64Data.split(',')[1];
149+
const document = new PdfDocument(pdf);
150+
151+
//flatten the annotation and form fields
152+
document.flatten = true;
153+
154+
var flattened = document.save();
155+
//laod the flattened PDF in PDF Viewer
156+
viewer.load(flattened, null);
157+
});
158+
159+
reader.readAsDataURL(file);
160+
}
161+
return (
162+
<div>
163+
<div className="control-section">
164+
<div style={{ display: 'none' }}>
165+
<UploaderComponent
166+
id="fileUpload"
167+
type="file"
168+
allowedExtensions=".pdf"
169+
selected={onSelect}
170+
></UploaderComponent>
171+
</div>
172+
{/* Render the PDF Viewer */}
173+
<PdfViewerComponent
174+
ref={(scope) => {
175+
viewer = scope;
176+
}}
177+
id="container"
178+
documentPath="https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf"
179+
resourceUrl="https://cdn.syncfusion.com/ej2/23.2.6/dist/ej2-pdfviewer-lib"
180+
enableAnnotation={true}
181+
enableFormFields={true}
182+
toolbarSettings={toolbarSettings}
183+
toolbarClick={toolbarClick}
184+
style={{ height: '640px' }}
185+
>
186+
<Inject services={[Toolbar, Annotation, FormFields, Magnification]} />
187+
</PdfViewerComponent>
188+
</div>
189+
</div>
190+
);
191+
}
192+
export default Default;
193+
194+
const root = createRoot(document.getElementById('sample'));
195+
root.render(<Default />);
196+
{% endraw %}
197+
{% endhighlight %}
198+
{% endtabs %}
199+
200+
N> Refer to the [Flatten on Download](../annotation/flatten-annotation#how-to-flatten-annotations) section for more information about flattening documents on download.
201+
76202
## Add Watermark or Stamp
77203
### UI-Level Stamps
78204
The PDF Viewer toolbar allows users to:

0 commit comments

Comments
 (0)