Document Processing

PSPDFKit for Web allows annotation flattening when exporting PDF documents.

PDF Exporting

PDF exporting can be done on the client (for both server-backed and standalone cases) as well as on the server (only the server-backed case).

Client-Side PDF Exporting

Regardless of the deployment option, you can always use Instance#exportPDF() to get the PDF content as an ArrayBuffer:

1
2
const content = await instance.exportPDF();
console.log(content); // => ArrayBuffer

Adding a download button to the toolbar

With instance.exportPDF() and the possibility of customizing the toolbar, you can easily add a download button to PSPDFKit for Web:

Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
const downloadButton = {
  type: "custom",
  id: "download-pdf",
  icon: "/download.svg",
  title: "Download",
  onPress: () => {
    pspdfkitInstance.exportPDF().then(buffer => {
      const blob = new Blob([buffer], { type: "application/pdf" });
      const fileName = "document.pdf";
      if (window.navigator.msSaveOrOpenBlob) {
        window.navigator.msSaveOrOpenBlob(blob, fileName);
      } else {
        const objectUrl = window.URL.createObjectURL(blob);
        const a = document.createElement("a");
        a.href = objectUrl;
        a.style = "display: none";
        a.download = fileName;
        document.body.appendChild(a);
        a.click();
        window.URL.revokeObjectURL(objectUrl);
        document.body.removeChild(a);
      }
    });
  }
};

const items = PSPDFKit.defaultToolbarItems;
// Add the download button to the toolbar.
items.push(downloadButton);

PSPDFKit.load({
  toolbarItems: items
});

Sending the PDF to a server

Here is an example showing how to send the ArrayBuffer that Instance#exportPDF() resolves with to a backend server using the Fetch API:

Copy
1
2
3
4
5
6
7
8
const arrayBuffer = await instance.exportPDF();
const blob = new Blob([arrayBuffer], { type: "application/pdf" });
const formData = new FormData();
formData.append("file", blob);
await fetch("/upload", {
  method: "POST",
  body: formData
});

In the example above, the backend server expects to receive a POST request with a content type of multipart/form-data through an /upload endpoint it exposes. The payload of the request will depend upon your specific backend implementation.

Server-Side PDF Exporting

To request the latest PDF from the server, please use the /pdf endpoint of the document API. You have the option to download the latest version with all annotations included (the default option) or to access the original PDF content that was initially uploaded. Keep in mind that annotations will never be flattened when using this API.

Exporting Changes Made to a PDF

Our recommendation for storing changes made to a PDF (e.g. annotations) is through Instant JSON. Importing and exporting a JSON file with the changes made to a document instead of doing this with the full PDF each time significantly reduces the bandwidth used.

Please see the importing and exporting section of our Instant JSON reference guide for examples of how to use Instant JSON.

We also support importing and exporting XFDF files. However, Instant JSON will result in smaller files and doesn’t have some of the limitations XFDF does. Please see our XFDF guide to learn more about our XFDF support.

Annotation Flattening

When flattening an annotation, the annotation is removed from the document, while its visual representation is kept intact. A flattened annotation is still visible but no longer editable by your users or by your app. This can be used, for example, to permanently apply annotations to your document, or to make annotations visible to viewers that otherwise can’t show annotations (like Safari on iOS). If not specified, an export will keep all annotations as they are.

To change how annotations are exported, use Instance#exportPDF(). This method accepts a flatten option:

1
2
const content = await instance.exportPDF({ flatten: true });
console.log(content); // => ArrayBuffer

Strategy When Applying Changes to a PDF

When exporting changes to an open document, two main strategies are available: incremental saving and full saving.

Incremental saving consists of always appending new changes to the end of a document and keeping the previous versions of it intact. Full saving, on the other hand, rewrites the entire document instead of appending changes at the end of it. This prevents the document file size from growing on every revision, but it is slower than incremental saving.

PSPDFKit for Web uses full saving by default. If you wish to use incremental saving instead, you have to set the incremental flag to true when calling Instance#exportPDF().