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 a database

Another option is to use a database. You can choose to store the XFDF string for the document and user as described in using files, but with a database you can store and organize the XFDF data so that the XFDF string for each annotation is separate, allowing you to update it individually instead of updating the entire XFDF file for every change. For example, you can store and organize XFDF strings based on a combination of factors like document ID, annotation ID, author, etc.

For example, with a relational database, you can have a table called Annotations which contains annotation ID, document ID and xfdfString columns. In this setup, you can fetch all annotations for a particular document, or just fetch one annotation you are interested in.

Saving annotations using a database

To save individual annotations separately, the getAnnotCommand and annotationChanged event are very useful. getAnnotCommand returns XFDF data for all of the annotations that have changed since the last time you called getAnnotCommand.

Annotations that have been added are inside the add element, modified annotations are in the modify element and deleted annotations have their id inside the delete element. If you call this function on the annotationChanged event, you can POST each command to your server to save each annotation change as it happens as opposed to having your user press a save button.

  .then(instance => {
    const { annotManager } = instance;
    annotManager.on('annotationChanged', (annotations, action, { imported }) => {
      // If the event is triggered by importing then it can be ignored
      // This will happen when importing the initial annotations from the server or individual changes from other users
      if (imported) return;

      const xfdfString = annotManager.getAnnotCommand();
      // <xfdf>
      //    <add>
      //      <text subject="Comment" page="0" color="#FFE6A2" ... />
      //    </add>
      //    <modify />
      //    <delete />
      // </xfdf>
      fetch('path/to/annotation/server', {
        method: 'POST',
        body: xfdfString // written to a database in the server
    // Full samples are available at the end of this section.

At this point you'll be saving annotations in realtime, so if you want to have a fully realtime solution you'll need to update annotations on each client in realtime. You can extend realtime saving further by hooking it up to a WebSocket, which can broadcast the new xfdfString in the database to be imported to all the clients. By utilizing getAnnotCommand instead of exportAnnotations you can greatly reduce the size of the data being transferred to/from the annotation server.

For samples about saving annotations into different databases, see links below:

Get the answers you need: Support


Free Trial

Get unlimited trial usage of PDFTron SDK to bring accurate, reliable, and fast document processing capabilities to any application or workflow.

Select a platform to get started with your free trial.

Unlimited usage. No email address required.

Join our live demo to learn about use cases & capabilities for WebViewer

Learn more