Some test text!


Import/export annotations

There are a few ways to import or export annotations such as from a file, a database, or a document. There are also more advanced loading options to help with finer control of the data.

Importing and exporting annotations using files

One of the options is to use XFDF files to save and load annotations. You can use AJAX requests to save and load the XFDF string from the server, and setup the server to write and read XFDF files. For example,

  .then(instance => {
    const { documentViewer, annotationManager } = instance.Core;

    documentViewer.setDocumentXFDFRetriever(async () => {
      // load the annotation data
      const response = await fetch('path/to/annotation/server');
      const xfdfString = await response.text();

      // <xfdf>
      //    <annots>
      //      <text subject="Comment" page="0" color="#FFE6A2" ... />
      //    </annots>
      // </xfdf>
      return xfdfString;

    // later save the annotation data
    // widgets and links will remain in the document without changing so it isn't necessary to export them
    annotationManager.exportAnnotations({ links: false, widgets: false }).then(xfdfString => {
      fetch('path/to/annotation/server', {
        method: 'POST',
        body: xfdfString // written into an XFDF file in server
      // Full samples are available at the end of this section.
Saving annotations using XFDF files

In the POST and GET requests you can pass an id to the server to uniquely identify the XFDF file that should be saved/loaded. You have full flexibility to choose this id but here are some simple examples:

  1. Use the filename as a unique identifier to have one XFDF file per document.
  2. Use a combination of the filename and username as a unique identifier to have one XFDF per user per document.

For samples about saving annotations into XFDF files in different backends, see Github repos below:

documentXFDFRetriever vs importAnnotations

Using the documentViewer.setXFDFRetriever or documentXFDFRetriever WebViewer constructor option is the preferred way of importing annotations from your server if you are adding them all at once initially.

  • WebViewer will process the internal annotations from the document asynchronously. If you try to import your annotations with importAnnotations and your server has modifications to an annotation inside the document, for example on page 10 and WebViewer hasn't loaded the annotations for page 10 yet then there may be a conflict when merging these changes together.
  • Using the annotationsLoaded event is one way to work around this so that there aren't any conflicts, however this event doesn't fire until annotations on every page have been loaded, so for documents with many pages this may take some time. It may also cause annotations to jump if the internal annotation has loaded on a page, then much later your server annotations are imported the annotation may change positions or even be deleted from the document.
  • documentXFDFRetriever merges your annotations at the proper time automatically and prevents conflicts and potential flashing of annotations on the page.

importAnnotations is fine for importing annotations later, after the document's internal annotations have loaded, however for the initial import of your server annotations documentXFDFRetriever is recommended instead.

Get the answers you need: Support

Upcoming Webinar: PDFTron SDK Tech Review | Nov 29, 2022 at 2 pm ET


The Platform


© 2022 PDFTron Systems Inc. All rights reserved.


Terms of Use