Xfdf configuration

WebViewer Version: ^7.2.0

Hello,
I have a problem with import and export xfdf of annotation. I import pdf file with annotations by using exportAnnotations function, where I put xfdf which looks like that(it’s a piece of code):

<stamp page=“0” rect=“1483.49,1639.8400000000001,1739.49,1895.8400000000001” color="#FF00FF" flags=“print” name=“94be1961-df58-0205-4a8c-849469ad728d” title=“8032” subject=“Stamp” rotation=“0” date=“D:20211014151905+02’00’” geometraOpacity=“0.5” rotationControlEnabled=“false” geometraBorderOpacity=“0.99” style=“dotted” status=“notStarted” readOnly=“false” opacity=“0.5” creationdate=“D:20211014133136+02’00’” icon=“Draft” maintainAspectRatio=“true” Hidden=“false”

When I export my pdf with annotations, using the same exportAnnotations function my xfdf of annotations is different, there is missing a lot of things:

<stamp color="#FF00FF" opacity=“0.5” creationdate=“D:20211014133136+02’00’” flags=“print” date=“D:20211014151943+02’00’” name=“94be1961-df58-0205-4a8c-849469ad728d” icon=“Draft” page=“0” rect=“1483.49,1639.84,1739.49,1895.84” subject=“Stamp” title=“8032”

How can I resolve this problem?

Hi,

Can I get more information about what you are doing (sample code would be helpful)? When you said
"I import pdf file with annotations by using exportAnnotations function",

Did you actually mean using loadDocument or importAnnotations? If you are using “importAnnotations”, does the “promise” it return resolve into an array of annotations?

Besides that, are you waiting for the “annotationsLoaded” event to fire before calling “exportAnnotations”? You can see the following link for more information
annotationsLoaded information

Lastly what type of information are you missing when you call “exportAnnotations”? Thank you

Best Regards,

Andrew Yip

Software Developer

PDFTron Systems, Inc.

www.pdftron.com

CONFIDENTIALITY NOTICE: This message (and any attachment to it) is intended only for the use of the individual or entity to which it is addressed in the header, and may contain information that is privileged, confidential and exempt from disclosure under applicable law. Any reproduction, distribution, modification or use of the contents of this message (and any attachment to it) by any individual or entity other than the intended recipient is prohibited. If you have received this communication in error, please notify us immediately and delete the original.

Sorry, my post was added incorrectly. Maybe I described this case a little wrong.
I export pdf with annotations which I added. I use this function:

 async saveDocumentToPdf() {
        if (this.WebViewer) {
            const tDocument = this.WebViewer.docViewer.getDocument();
            if (!tDocument) {
                return;
            }
            this.printLock = true;
            const am = this.WebViewer.docViewer.getAnnotationManager();
            _.forEach(am.getSelectedAnnotations(), (annot) => {
                annot.Printable = true;
            });
            try {
                let additionalAnnotsToPrint = await this.webviewerInit.getPrintHelper().getDisplayValuesAnnotations(am);
                additionalAnnotsToPrint = additionalAnnotsToPrint.concat(am.getSelectedAnnotations());
                const xfdf = await am.exportAnnotations({ annotList: additionalAnnotsToPrint });
                const options = {
                    xfdfString: xfdf,
                };
                const data = await tDocument.getFileData(options);
                const blob = new Blob([data], { type: "application/pdf" });

                const link = document.createElement("a");
                link.href = window.URL.createObjectURL(blob);
                let filename = "";
                const file = FileStore.getFileById(this.ActiveFileId);
                if (file) {
                    filename = file.name;
                }
                link.download = filename;
                link.click();
                _.forEach(am.getSelectedAnnotations(), (annot) => {
                    this.initPdfAnnotationAsSelected(annot);
                });
            } catch (error) {
                console.log("error: ", error.stack);
            }
            this.printLock = false;
        }
    },

In this function my annotation has xfdf which has a lot of informations:
<stamp page=“0” rect=“1483.49,1639.8400000000001,1739.49,1895.8400000000001” color="#FF00FF" flags=“print” name=“94be1961-df58-0205-4a8c-849469ad728d” title=“8032” subject=“Stamp” rotation=“0” date=“D:20211014151905+02’00’” geometraOpacity=“0.5” rotationControlEnabled=“false” geometraBorderOpacity=“0.99” style=“dotted” status=“notStarted” readOnly=“false” opacity=“0.5” creationdate=“D:20211014133136+02’00’” icon=“Draft” maintainAspectRatio=“true” Hidden=“false”

Then I use function below to upload this previous exported pdf with annotation:

async uploadPdfFileWithAnnotations(uploadAnnotations = false) {
        const annotationManager = this.webViewer.annotManager;
        const detectedAnnotations = annotationManager.getAnnotationsList();

        const xfdf = await annotationManager.exportAnnotations({ annotList: [] });
        const options = {
            xfdfString: xfdf,
        };
        const tDocument = await this.webViewer.docViewer.getDocument();
        const data = await tDocument.getFileData(options);
        const blob = new Blob([data], { type: "application/pdf" });
        this.uploadedPdfFile.file = blob;

        if (uploadAnnotations) {
            const xfdfPromise = map(detectedAnnotations, (annot) => annotationManager.exportAnnotations({ annotList: [annot] }));
            const xfdfPromiseList = await Promise.all(xfdfPromise);
            const annotsToCreate = map(detectedAnnotations, (annot, index) => {
                const newUUID = AnnotationStore.generateUUID();
                return {
                    estimateId: EstimateStore.getActiveEstimate().id,
                    annotationId: newUUID,
                    name: annot.annotationName || annot.Subject,
                    number: annot.annotationNumber || "000",
                    xfdf: xfdfPromiseList[index].replace(annot.av, newUUID),
                    type: annot.Subject,
                    height: annot.height || "2.5",
                    quantity: annot.quantity || 1,
                    layerId: "-1",
                };
            });
            if (!this.multipleFliesDataLoader.uploadingFiles) this.initLoaderForSinglePDFUpload(true);
            if (!this.multipleFliesDataLoader.uploadingPDFwithAnnots) this.multipleFliesDataLoader.uploadingPDFwithAnnots = true;
            this.onUploadFile({ ...this.uploadedPdfFile, annotations: annotsToCreate });
            this.uploadedPdfFile = {};
        } else {
            if (!this.multipleFliesDataLoader.uploadingFiles) this.initLoaderForSinglePDFUpload(false);
            try {
                this.onUploadFile(this.uploadedPdfFile);
                this.uploadedPdfFile = {};
            } catch (error) {
                console.log("error: ", error.stack);
            }
        }
    },

but import function return xfdf which is shorter and some of values are missing:
<stamp color="#FF00FF" opacity=“0.5” creationdate=“D:20211014133136+02’00’” flags=“print” date=“D:20211014151943+02’00’” name=“94be1961-df58-0205-4a8c-849469ad728d” icon=“Draft” page=“0” rect=“1483.49,1639.84,1739.49,1895.84” subject=“Stamp” title=“8032”

Hi,

Thank you for the detailed description of what you are doing. Can I get more detailed on how you are exporting annotations to get

<stamp page=“0” rect=“1483.49,1639.8400000000001,1739.49,1895.8400000000001” color="#FF00FF" flags=“print” name=“94be1961-df58-0205-4a8c-849469ad728d” title=“8032” subject=“Stamp” rotation=“0” date=“D:20211014151905+02’00’” geometraOpacity=“0.5” rotationControlEnabled=“false” geometraBorderOpacity=“0.99” style=“dotted” status=“notStarted” readOnly=“false” opacity=“0.5” creationdate=“D:20211014133136+02’00’” icon=“Draft” maintainAspectRatio=“true” Hidden=“false”

For the missing data you are seeing there are a number of reasons why they don’t appear when you export annotations.

We don’t include XFDF for default values, so

  • rotation: Won’t appear in the XFDF when it’s 0, since 0 is the default value
  • readOnly: Only appear in the XFDF when it’s true, since false is the default value
  • Hidden: Only appear in the XFDF when it’s true, since false is the default value

Properties that we have on annotation objects but are not part of the XFDF specification, aren’t included when exporting XFDF. The following values won’t be included

  • maintainAspectRatio
  • rotationControlEnabled
  • geometraOpacity
  • geometraBorderOpacity
  • status

For custom data you can store them as “custom data” and set them when reloading. You can find out more in the following guide

Lastly for “style”, it should be included in the XFDF for free text annotations ( and a few other) however not for stamp annotations (in the sample you gave) since you can’t really apply a style to a sample.

Please let me know if the above helps

Best Regards,

Andrew Yip

Software Developer
PDFTron Systems, Inc.
www.pdftron.com