Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Document-Processing-toc.html
Original file line number Diff line number Diff line change
Expand Up @@ -998,6 +998,7 @@
<li><a href="/document-processing/pdf/pdf-viewer/react/annotation/signature-annotation">Handwritten Signature</a></li>
<li><a href="/document-processing/pdf/pdf-viewer/react/annotation/line-angle-constraints">Line Angle Constraint</a></li>
<li><a href="/document-processing/pdf/pdf-viewer/react/annotation/custom-data">Adding custom Data in annotations</a></li>
<li><a href="/document-processing/pdf/pdf-viewer/react/annotation/flatten-annotation">Flatten Annotations into the PDF </a></li>
<li>Export and Import Annotations
<ul>
<li><a href="/document-processing/pdf/pdf-viewer/react/annotation/export-import/export-annotation">Export Annotation</a></li>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
---
layout: post
title: Flatten Annotations Before Saving the PDF | Syncfusion
description: Learn how all about how to flatten annotations and formfields before saving a PDF in the Syncfusion React PDF Viewer.
platform: document-processing
control: PDF Viewer
documentation: ug
domainurl: ##DomainURL##
---

# Flatten Annotations Before Saving the PDF in React
Flattening annotations permanently merges them into the PDF content. Once flattened:
- Annotations are **no longer editable** in any PDF viewer.
- Useful for **secure sharing**, preventing modifications.
- Ideal when **finalizing markup** before distribution.

## How to Flatten Annotations

To flatten documents when they are uploaded/loaded into the viewer, see [Flatten on Load](../document-handling/preprocess-pdf#flatten-on-load).

Use the example below to flatten at export time (on download).

{% tabs %}
{% highlight js tabtitle="Standalone" %}
{% raw %}
import { createRoot } from 'react-dom/client';
import './index.css';
import * as React from 'react';
import {
PdfViewerComponent,
Toolbar,
Magnification,
Navigation,
LinkAnnotation,
BookmarkView,
ThumbnailView,
Print,
TextSelection,
TextSearch,
Annotation,
FormFields,
FormDesigner,
PageOrganizer,
Inject,
} from '@syncfusion/ej2-react-pdfviewer';
import {
PdfDocument
} from '@syncfusion/ej2-pdf';

function Default() {
let viewer;

const flattenPdf = () => {
viewer.saveAsBlob().then((value) => {
const reader = new FileReader();
reader.onloadend = function () {
const arrayBuffer = reader.result;
const byteArray = new Uint8Array(arrayBuffer);
const document = new PdfDocument(byteArray);
// Flatten all annotations and form fields
document.flatten = true;
document.save('flattened.pdf');
};
reader.readAsArrayBuffer(value);
});
};

return (
<div>
<div className="control-section">
<button onClick={flattenPdf}>Flatten and download PDF</button>

<PdfViewerComponent
ref={(scope) => { viewer = scope; }}
id="container"
documentPath="https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf"
resourceUrl="https://cdn.syncfusion.com/ej2/23.2.6/dist/ej2-pdfviewer-lib"
style={{ height: '640px' }}
>
<Inject
services={[
Toolbar,
Magnification,
Navigation,
LinkAnnotation,
BookmarkView,
ThumbnailView,
Print,
TextSelection,
TextSearch,
Annotation,
FormFields,
FormDesigner,
PageOrganizer,
]}
/>
</PdfViewerComponent>
</div>
</div>
);
}
export default Default;

const root = createRoot(document.getElementById('sample'));
root.render(<Default />);
{% endraw %}
{% endhighlight %}
{% endtabs %}


## Notes

- Flattening applies to **all annotation types**: text markup, shapes, stamps, notes, ink, and form fields.
- Once flattened, annotations **cannot be edited or removed**.
- Use flattening **only at export time**, not during regular document interactions.

## See also

- [Annotation Overview](../overview)
- [Annotation Types](../annotation/annotation-types/area-annotation)
- [Annotation Toolbar](../toolbar-customization/annotation-toolbar)
- [Create and Modify Annotation](../annotation/create-modify-annotation)
- [Customize Annotation](../annotation/customize-annotation)
- [Handwritten Signature](../annotation/signature-annotation)
- [Export and Import Annotation](../annotation/export-import/export-annotation)
- [Annotation Permission](../annotation/annotation-permission)
- [Annotation in Mobile View](../annotation/annotations-in-mobile-view)
- [Annotation Events](../annotation/annotation-event)
- [Annotation API](../annotation/annotations-api)
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,221 @@ doc.annotations.flattenAllAnnotations();
const bytes = await doc.save();
```

### Flatten on Load

Use the following code-snippet, when you want uploaded PDFs to be flattened before they are loaded into the viewer.

{% tabs %}
{% highlight js tabtitle="Standalone" %}
{% raw %}
import { createRoot } from 'react-dom/client';
import './index.css';
import * as React from 'react';
import {
PdfViewerComponent,
Toolbar,
Annotation,
FormFields,
Inject,
Magnification,
} from '@syncfusion/ej2-react-pdfviewer';
import { PdfDocument, _encode } from '@syncfusion/ej2-pdf';
import { UploaderComponent } from '@syncfusion/ej2-react-inputs';
function Default() {
let viewer;
const openFile = {
prefixIcon: 'e-icons e-folder',
id: 'openPdf',
tooltipText: 'Open File',
align: 'left',
};
const extensions = '.pdf';
const toolbarSettings = {
showTooltip: true,
toolbarItems: [
openFile,
'PageNavigationTool',
'MagnificationTool',
'PanTool',
'SelectionTool',
'SearchOption',
'PrintOption',
'UndoRedoTool',
'AnnotationEditTool',
'FormDesignerEditTool',
'CommentTool',
'SubmitForm',
'DownloadOption',
],
};

function toolbarClick(args) {
if (args.item && args.item.id === 'openPdf') {
document
.getElementsByClassName('e-file-select-wrap')[0]
.querySelector('button')
.click();
}
}
function onSelect(args) {
let validFiles = args.filesData;
if (validFiles.length === 0) {
args.cancel = true;
return;
}
if (!extensions.includes(validFiles[0].type)) {
args.cancel = true;
return;
}

let file = validFiles[0].rawFile;
let reader = new FileReader();

reader.addEventListener('load', () => {
let base64Data = reader.result;
let pdf = base64Data.split(',')[1];
const document = new PdfDocument(pdf);

//flatten the annotation and form fields
document.flatten = true;

var flattened = document.save();
//laod the flattened PDF in PDF Viewer
viewer.load(flattened, null);
});

reader.readAsDataURL(file);
}
return (
<div>
<div className="control-section">
<div style={{ display: 'none' }}>
<UploaderComponent
id="fileUpload"
type="file"
allowedExtensions=".pdf"
selected={onSelect}
></UploaderComponent>
</div>
{/* Render the PDF Viewer */}
<PdfViewerComponent
ref={(scope) => {
viewer = scope;
}}
id="container"
documentPath="https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf"
resourceUrl="https://cdn.syncfusion.com/ej2/23.2.6/dist/ej2-pdfviewer-lib"
enableAnnotation={true}
enableFormFields={true}
toolbarSettings={toolbarSettings}
toolbarClick={toolbarClick}
style={{ height: '640px' }}
>
<Inject services={[Toolbar, Annotation, FormFields, Magnification]} />
</PdfViewerComponent>
</div>
</div>
);
}
export default Default;

const root = createRoot(document.getElementById('sample'));
root.render(<Default />);
{% endraw %}
{% endhighlight %}
{% endtabs %}

### Flatten on Download

Use the following code-snippet to flatten all annotations and form fields at export time, then download the flattened PDF.

{% tabs %}
{% highlight js tabtitle="Standalone" %}
{% raw %}
import { createRoot } from 'react-dom/client';
import './index.css';
import * as React from 'react';
import {
PdfViewerComponent,
Toolbar,
Magnification,
Navigation,
LinkAnnotation,
BookmarkView,
ThumbnailView,
Print,
TextSelection,
TextSearch,
Annotation,
FormFields,
FormDesigner,
PageOrganizer,
Inject,
} from '@syncfusion/ej2-react-pdfviewer';
import {
PdfDocument
} from '@syncfusion/ej2-pdf';

function Default() {
let viewer;

const flattenPdf = () => {
viewer.saveAsBlob().then((value) => {
const reader = new FileReader();
reader.onloadend = function () {
const arrayBuffer = reader.result;
const byteArray = new Uint8Array(arrayBuffer);
const document = new PdfDocument(byteArray);
// Flatten all annotations and form fields
document.flatten = true;
document.save('flattened.pdf');
};
reader.readAsArrayBuffer(value);
});
};

return (
<div>
<div className="control-section">
<button onClick={flattenPdf}>Flatten and download PDF</button>

<PdfViewerComponent
ref={(scope) => { viewer = scope; }}
id="container"
documentPath="https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf"
resourceUrl="https://cdn.syncfusion.com/ej2/23.2.6/dist/ej2-pdfviewer-lib"
style={{ height: '640px' }}
>
<Inject
services={[
Toolbar,
Magnification,
Navigation,
LinkAnnotation,
BookmarkView,
ThumbnailView,
Print,
TextSelection,
TextSearch,
Annotation,
FormFields,
FormDesigner,
PageOrganizer,
]}
/>
</PdfViewerComponent>
</div>
</div>
);
}
export default Default;

const root = createRoot(document.getElementById('sample'));
root.render(<Default />);
{% endraw %}
{% endhighlight %}
{% endtabs %}

## Add Watermark or Stamp
### UI-Level Stamps
The PDF Viewer toolbar allows users to:
Expand Down