PDF.js Express Plusplay_arrow

Professional PDF.js Viewing & Annotations - Try for free

side menu

Get Started

play_arrow

Learn more

play_arrow

Common use cases

play_arrow

Open a document

play_arrow

Save a document

play_arrow

Viewer

play_arrow

UI Customization

play_arrow

Annotations

play_arrow

Collaboration

play_arrow

Forms

play_arrow

Signature

play_arrow

Searching

play_arrow

Measurement

play_arrow

Compare

play_arrow

Advanced Capabilities

play_arrow

PDF.js Express REST API

play_arrow

Migration Guides

play_arrow

Open a document, add annotations, download

The following features are available in:

check

PDF.js Express Viewer

help_outline

PDF.js Express Viewer is a free viewer with limited capabilities compared to PDF.js Express Plus

check

PDF.js Express Plus

help_outline

PDF.js Express Plus is a commercial PDF SDK for viewing, annotating, signing, form filling and more

A very common use case for a PDF viewer is allowing a user to upload a document, annotate it, and then download it with those annotations.

This flow is easy to set up in PDF.js Express using the PDF.js Express REST API

This guide assumes that you have PDF.js Express installed, and have it integrated into your app. If you have no done so, please follow the guides here for integrating it into your app.

1. Disable flattened annotations

By default PDF.js Express renders annotations as a flattened bitmap. We want to disable this because we will be using the extract api to load annotations instead.

To disable these annotations, add the disableFlattenedAnnotations flag to the constructor.

import WebViewer from '@pdftron/pdfjs-express'

WebViewer({
  disableFlattenedAnnotations: true,
  ...otherOptions
}).then(instance => {
  // ...
})

2. Listen for document load

Every time a new document is loaded, we want to extract the annotations from it and load them into the viewer. This can be done by using a document listener and the PDF.js Express extract API. In this example we will also use the recommended PDF.js Express API SDK

import WebViewer from '@pdftron/pdfjs-exress'
import ExpressUtils from '@pdftron/pdfjs-express-utils'

WebViewer({
  disableFlattenedAnnotations: true,
  ...otherOptions
}).then(instance => {

  // Create a new instance of the utility SDK
  const utils = new ExpressUtils();

  const { documentViewer, annotationManager } = instance.Core;

  // Set a callback function for every time a document is loaded
  documentViewer.addEventListener('documentLoaded', async () => {
    // Get the loaded document's data
    const data = await documentViewer.getDocument().getFileData();
    // Set the file in the SDK
    utils.setFile(data);
    // Use the API to extract the XFDF
    const { xfdf } = await utils.extract();
    // Loading the resulting XFDF into the viewer
    const importedAnnotations = await annotationManager.importAnnotations(xfdf);
  })
})

Note: You can load documents using the loadDocument api. See more info here.

3. Downloading the file

After the user has annotated the file, they might want to download it. In order to bake the annotations they have added into the document, we need to use the merge endpoint. The following sample shows the easiest way to do this.

Note: We will use the file-saver package to help us trigger a download.

import FileSaver from 'file-saver'
import WebViewer from '@pdftron/pdfjs-exress'
import ExpressUtils from '@pdftron/pdfjs-express-utils'

WebViewer({
  disableFlattenedAnnotations: true,
  ...otherOptions
}).then(instance => {

  // Create a new instance of the utility SDK
  const utils = new ExpressUtils();

  const { documentViewer, annotationManager } = instance.Core;

  // ... documentLoaded code from above

  // A function that gets called when the user clicks your download button.
  // This can be implemented any way you want.
  // In our example we will assume it is bounded to an '#download-button' button
  document.getElementById('download-button').onclick = () => {

    // Get the annotations and the documents data
    const xfdf = await annotationManager.exportAnnotations({});
    const fileData = await documentViewer.getDocument().getFileData({});

    // Set the annotations and document into the Utility SDK, then merge them together
    const resp = await utils
      .setFile(fileData)
      .setXFDF(xfdf)
      .merge();

    // Get the resulting blob from the merge operation
    const mergedBlob = await resp.getBlob();

    // trigger a download for the user!
    FileSaver.saveAs(mergedBlob, 'myfile.pdf')
  }
})