Using XFDF format to import & export annotation data

According to the XFDF specification:

XFDF (XML Forms Data Format) is a format for representing forms data and annotations in a PDF document. XFDF is the XML version of Forms Data Format (FDF), a simplified version of PDF for representing forms data and annotations.

Examples

XML

1<?xml version="1.0" encoding="UTF-8" ?>
2<xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve">
3 <fields>
4 <field name="ACombo"><value>Red</value></field>
5 </fields>
6 <annots>
7 <square subject="Rectangle" page="0" rect="306.01,744.85,408.98,775.94" flags="print" name="447c49b7-5e50-4b13-adc8-c291102466e6" title="Guest" date="D:20171226120150-08'00'" color="#000000" width="5" creationdate="D:20171226120147-08'00'">
8 <popup flags="print,nozoom,norotate" page="0" rect="0,767,112.5,842" open="no"/>
9 </square>
10 </annots>
11</xfdf>

The fields section contains the names and values of any form fields in the document. In annots all of the annotation data is found.

In WebViewer

WebViewer provides methods to import annotations into the viewer from their XFDF data as well as export all currently loaded annotations as XFDF using AnnotationManager.

1WebViewer(...)
2 .then(instance => {
3 const { annotationManager } = instance.Core;
4 // import asynchronously
5 // you might call this after fetching the XFDF data as a string from your server
6 annotationManager.importAnnotations(xfdfData);
7
8 // get all annotation and form data
9 // you might call this when you want to pass the XFDF data to your server to be saved
10 // or you may want to pass an XFDF string to doc.getFileData to embed the annotations
11 // in the downloaded PDF
12 annotationManager.exportAnnotations().then(xfdfData => { });
13
14 // if you're saving the XFDF to your server and calling importAnnotations when loading
15 // you may not want to save the widgets and links if they won't be changing in the document
16 // this is because widgets and links don't have unique ids so WebViewer isn't always able
17 // to merge them together without duplicating them when calling importAnnotations
18 // as long as you save the field values then changes made to the fields (e.g. checking a checkbox)
19 // will be saved
20 // if you don't need to save field values either you can use "fields: false"
21 annotationManager.exportAnnotations({
22 widgets: false,
23 links: false
24 //fields: false
25 }).then(annotData => { })
26
27 // only get XFDF data for specified annotations
28 // this might be useful if you save the XFDF data separately per user on your server
29 // and you want to get the XFDF data for a particular user's annotations
30 // it can also be useful if you want to get the XFDF for a particular annotation
31 // because you're saving each annotation in a separate database row on your server
32 annotationManager.exportAnnotations({
33 annotList: [annot1, annot2]
34 }).then(annotData => { })
35 })

WebViewer also provides a way to get the XFDF data for annotations that have changed recently in the viewer. AnnotationManager.exportAnnotationCommand will get the XFDF data for annotations that have been added, modified or deleted since the last time exportAnnotationCommand was called.

A command looks something like this:

XML

1<?xml version="1.0" encoding="UTF-8" ?>
2<xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve">
3<fields />
4<add>
5 <text subject="Comment" page="0" rect="262.13,465.90,285.38,489.15" flags="print,nozoom,norotate" name="651eab92-9258-f676-b5c0-9767cb1ab932" title="Guest" date="D:20171226125004-08'00'" color="#FFFF00" opacity="0.5" creationdate="D:20171226125004-08'00'" icon="Comment">
6 <popup flags="print,nozoom,norotate" page="0" rect="0,573,112.5,648" open="no"/>
7 </text>
8</add>
9<modify>
10 <text subject="Comment" page="0" rect="110.47,367.84,133.72,391.09" flags="print,nozoom,norotate" name="e89d6405-fdcc-aa2b-9ebb-cc9d8a525ca2" title="Guest" date="D:20171226125247-08'00'" color="#FFFF00" opacity="0.5" creationdate="D:20171226125238-08'00'" icon="Comment">
11 <popup flags="print,nozoom,norotate" page="0" rect="0,573,112.5,648" open="no"/>
12 </text>
13</modify>
14<delete>
15 <id page="0">e2976b7b-075b-cad9-0f9f-fe0de613a543</id>
16</delete>
17</xfdf>

Commands can be imported using AnnotationManager.importAnnotationCommand. This is the technique that is used in the realtime collaboration example.

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales