Export annotations without custom data

WebViewer Version: 8.4.0

"No" to all of these questions:

  • Do you have an issue with a specific file(s)?
  • Can you reproduce using one of our samples or online demos?
  • Are you using the WebViewer server?
  • Does the issue only happen on certain browsers?
  • Is your issue related to a front-end framework?

Is your issue related to annotations? Yes

We leverage annotation custom data to persist a UUID corresponding to a related database entity; this enables us to synchronize existing annotation changes with our database.

We enable users to download a PDF version of a file with exported/embedded annotations on the client-side. Here is the snippet we’re using for this process:

const doc = webViewer.Core.documentViewer.getDocument();
const xfdfString = await webViewer.Core.annotationManager.exportAnnotations();
const data = await doc.getFileData({
    // saves the document with annotations in it
    xfdfString,
    downloadType: 'pdf',
});
const arr = new Uint8Array(data);
const blob = new Blob([arr], { type: 'application/pdf' });

downloadBlob(blob, fileName);

The exported annotations contain the custom data key mentioned above. Is there a way to export annotations excluding this custom data? This custom data is not inherently problematic to the downloaded PDF file itself; however, it is posing issues for us in a downstream flow post-download.

Hello, I’m Ron, an automated tech support bot :robot:

While you wait for one of our customer support representatives to get back to you, please check out some of these documentation pages:

Guides:APIs:Forums:

Hello Nick,

We currently don’t have an easy way to do this, since we store rich text data inside custom-data for FreeText. You could remove the custom data then add it back in the annotation when done exporting.

However, if you’re creating a UUID for each annotation you can use the Id property that we assign to annotations uniquely

Let me know if this works for you!

Best regards
Tyler Gordon
Web Development Support Engineer
PDFTron

Thanks for the reply, Tyler. The first option might work but does not seem ideal.

An alternative place in which we could solve our problem would be at time of initial document load. Currently, we draw the set of database-persisted annotations onto documents via a snippet that looks like this:

const importedAnnotations = await Promise.all(
    loadedAnnotations.map(async ({ xfdf }) => {
        return (await annotationManager.importAnnotations(xfdf))[0];
    })
);

await annotationManager.drawAnnotationsFromList(
    compact(importedAnnotations)
);

This works well.

However, some PDF documents are uploaded with an initial set of internal/local annotations. These annotations are not persisted to the database and cause various issues when users attempt to edit them. Is there a way to interact with the initial set of internal annotations (i.e. iterate over them and interact with custom data and/or other Core.Annotations.Annotation properties)?

Hello Nick,

You can check which annotations are internal to a document (on the original document that was uploaded) with the annotation function: isInternal()

Does that work for you?

Best regards,
Tyler Gordon
Web Development Support Engineer
PDFTron

Thanks, Tyler. I noticed the isInternal() method.

How are we able to retrieve the full set of Core.Annotations.Annotation objects after the document has been loaded? I am only aware of the ability to export annotations to an XFDF string via AnnotationManager.exportAnnotations which isn’t helpful.

Hello nick,

You can get the list of annotations that are on the document by doing
instance.Core.annotationManager.getAnnotationsList()

Is this what youre looking for?

Best regards,
Tyler Gordon
Web Development Support Engineer
PDFTron

Tyler, unless I’m missing something, that does not include the initial internal set of annotations. For example:

  1. load document with some internal annotations (i.e. test.pdf (42.8 KB))
  2. invoke annotationManager.getAnnotationsList() after the document has loaded
  3. see that it returns an empty array

Hello nick,

Does this code snippet provide an empty array?

webViewer.Core.documentViewer.addEventListener('annotationsLoaded', () => {
    console.log('Annotations: ', webViewer.Core.annotationManager.getAnnotationsList())
})

There are two events and if youre listening to documentLoaded to get the annotations, it would usually fail because annotations have not been parsed yet. I would listen to the annotationsLoaded event, which occurs right after documentLoaded

I loaded the document into our demo, and got the annotationList and it resulted in 2 annotations:

Best regards
Tyler Gordon
Web Development Support Engineer
PDFTron

1 Like

Thanks, Tyler! That’s what I was missing – the annotationsLoaded event.