Some test text!

Hamburger Icon

Web / Guides

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 Salesforce

Another option for importing and exporting annotation is using Salesforce custom objects to store XFDF data if you are hosting WebViewer in the Salesforce platform. You can create custom object in Salesforce setting page or using sfdx command line utility tool. In this example we will create Apex class called AnnotationController.cls which will utitlise Salesforce SOQL to store and retrieve XFDF data to and from custom objects.

Create custom object in Salesforce setting page, under Manage Objects section. Here is a sample custom object used in this sample alt text

Apex class for storing and retrievin annotation XFDF data.

public with sharing class AnnotationController {
    public static String saveAnnotations(String action, String documentId, String annotationId, String xfdfString) {
        PDFTronAnnotations__c[] annots = [SELECT Id, Content_Version_Id__c, Annotation_Id__c, xfdfString__c
            FROM PDFTronAnnotations__c WHERE Annotation_Id__c = :annotationId];

        Pattern MyPattern = Pattern.compile('<delete>(.*)</delete>');
        Matcher MyMatcher = MyPattern.matcher(xfdfString);
        Boolean isDeleteCommand = MyMatcher.matches();

        if (action == 'delete') {
            // Delete record
            delete annots;
            return 'Success';
        } else if (annots.size() == 0) {
            // Create new record
            PDFTronAnnotations__c newAnnot = new PDFTronAnnotations__c(
            insert newAnnot;
            return newAnnot.Id;
        } else {
            // Update record
            annots[0].xfdfString__c = xfdfString;
            update annots;
            return annots[0].Id;

    public static List<Map<String,String>> getAnnotations(String documentId) {
        List<PDFTronAnnotations__c> temp = [SELECT Id, Content_Version_Id__c, Annotation_Id__c, xfdfString__c FROM PDFTronAnnotations__c WHERE Content_Version_Id__c = :documentId];
        List<Map<String,String>> annotations = new List<Map<String,String>>();
        for (Integer i = 0; i < temp.size(); i++) {
            Map<String,String> annot = new Map<String, String>();
            annot.put('xfdfString', temp[i].xfdfString__c);
            annot.put('Annotation_Id', temp[i].Annotation_Id__c);
            annot.put('ContentVersion_Id', temp[i].Content_Version_Id__c);
        return annotations;


// Full sample is available at the end of this section.

Sample app in Lightning Web Component to showcase importing and exporting XFDF stirng to Salesforce custom object.

/** AnnotationController.getAnnotations(id) Apex method */
import getAnnotations from '@salesforce/apex/AnnotationController.getAnnotations';
/** AnnotationController.saveAnnotations(params) Apex method */
import saveAnnotations from '@salesforce/apex/AnnotationController.saveAnnotations';

export default class WvInstance extends LightningElement {
  // Snipped for brevity
  initUI() {
    // ...
    const viewer = new PDFTron.WebViewer({...}, viewerElement);
    viewerElement.addEventListener('ready', () => {
      this.iframeWindow = viewerElement.querySelector('iframe').contentWindow;

  // Snipped for brevity
  handleReceiveMessage(event) {
    if (event.isTrusted && typeof === 'object') {
      switch ( {
        case 'LOAD_ANNOTATIONS':
            * Retrieve/import annotation for the loaded document
            * @param {string} documentId unique id of the loaded document
            * @returns {string} xfdf string
            .then(result => {
                { type: 'LOAD_ANNOTATIONS_FINISHED', result },
        case 'SAVE_ANNOTATIONS':
            * Storing/exporting XFDF string to Salesforce custom object
            * @param {string} action type of action, e.g. delete, update,
            * @param {string} documentId unique id of the document
            * @param {string} annotationId id of the annotation
            * @param {string} xfdfString xfdf string

  // Snipped for brevity

Have questions? Connect with our experts on Discord.