In my application annotations are stored in the database as single annotations. For one document in the document table I store many annotations (multiple xfdf strings) in the annotation table. I wrote a code to generate the pdf and import these annotations. I referred following links for this code,
- https://www.pdftron.com/documentation/web/guides/features/forms/import-data/
- https://groups.google.com/g/pdfnet-sdk/c/gXaG5X-zpR8
params,
- annotations : list of annotations with xfdf String
- downloadedFile : pdf file as a buffer
- isFlatternAnnotations - is a boolean option to flatten annotations
async importAnnotationsToDocument(
annotations: any,
downloadedFile: any,
isFlatternAnnotations: any,
) {
await PDFNet.initialize();
const pdfDocument = await PDFNet.PDFDoc.createFromBuffer(downloadedFile);
pdfDocument.lock();
let fdfDocument = null;
annotations.forEach(async annotation => {
fdfDocument = await PDFNet.FDFDoc.createFromXFDF(annotation.xfdfString);
await pdfDocument.fdfMerge(fdfDocument);
});
if (isFlatternAnnotations === 'true') {
await pdfDocument.flattenAnnotations();
}
const documentBuffer = await pdfDocument.saveMemoryBuffer(
PDFNet.SDFDoc.SaveOptions.e_remove_unused,
);
const documentBufferResponse = Buffer.from(documentBuffer);
PDFNet.shutdown();
return documentBufferResponse;
}
However I noticed the code is working only the await pdfDocument.flattenAnnotations();
is running. If it is not running annotations are not merged in the document.
And also if it runs a single time, the annotations are displayed without flattening. But if I add the same line three times it works correctly.
I think the way I have done this is not correct. I need your help to write this code correctly.
Following code works correctly, but there should be a proper way to do this.
async importAnnotationsToDocument(
annotations: any,
downloadedFile: any,
isFlatternAnnotations: any,
) {
await PDFNet.initialize();
const pdfDocument = await PDFNet.PDFDoc.createFromBuffer(downloadedFile);
pdfDocument.lock();
let fdfDocument = null;
annotations.forEach(async annotation => {
fdfDocument = await PDFNet.FDFDoc.createFromXFDF(annotation.xfdfString);
await pdfDocument.fdfMerge(fdfDocument);
});
if (isFlatternAnnotations === 'true') {
await pdfDocument.flattenAnnotations();
await pdfDocument.flattenAnnotations();
await pdfDocument.flattenAnnotations();
} else {
// This shows the annotations without flattening
await pdfDocument.flattenAnnotations();
}
const documentBuffer = await pdfDocument.saveMemoryBuffer(
PDFNet.SDFDoc.SaveOptions.e_remove_unused,
);
const documentBufferResponse = Buffer.from(documentBuffer);
PDFNet.shutdown();
return documentBufferResponse;
}
Following is the xfdf String for a single annotation
<?xml version="1.0" encoding="UTF-8"?>
<xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve">
<fields />
<add>
<square page="0"
rect="387.88,525.73,525,609.07"
color="#FFCD45" flags="print"
name="d1aa1a2a-822f-507b-6ff6-d61bcc6bd862"
title="test.title" subject="Rectangle"
date="D:20210405104448+08'00'"
interior-color="#FFCD45"
opacity="0.5"
creationdate="D:20210405104445+08'00'" />
</add>
<modify /><delete />
</xfdf>