使用 NodeJs 在 Pdftron 中导入多个注释

Posted

技术标签:

【中文标题】使用 NodeJs 在 Pdftron 中导入多个注释【英文标题】:Import multiple Annotations in Pdftron with NodeJs 【发布时间】:2021-03-26 03:46:41 【问题描述】:

在我的应用程序中,注释作为单个注释存储在数据库中。对于文档表中的一个文档,我在注释表中存储了许多注释(多个 xfdf 字符串)。 我编写了一个代码来生成 pdf 并导入这些注释。我为此代码引用了以下链接,

https://www.pdftron.com/documentation/web/guides/features/forms/import-data/ https://groups.google.com/g/pdfnet-sdk/c/gXaG5X-zpR8

参数,

annotations : 带有 xfdf 字符串的注释列表 downloadedFile : pdf 文件作为缓冲区 isFlatternAnnotations - 是一个布尔选项 展平注释
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;

但是我注意到代码只有 await pdfDocument.flattenAnnotations(); 正在运行。如果它未运行,则注释不会合并到文档中。 而且,如果它运行一次,注释会显示而不会展平。但是,如果我将同一行添加 3 次,它就可以正常工作。 我认为我这样做的方式是不正确的。我需要您的帮助才能正确编写此代码。

以下代码可以正常工作,但应该有适当的方法来做到这一点。

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;
  

以下是单个注释的 xfdf 字符串

<?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>

【问题讨论】:

PDFNet 有两种类型的 XFDF 文件,Regular 和 Command。您可以通过查看 XFDF 并查看是否有 ***元素来告诉命令。如果那是您的 XFDF 字符串的格式,那么您使用不同的 API。如果存在这些值,请告诉我,我可以提供进一步的建议(理想情况下,您可以在问题中提供这些 XFDF 字符串之一的示例)。 @Ryan 很抱歉回复得太晚了。我已经添加了 xfdf 字符串。 感谢您的更新,这确认您使用的是备用 XFDF 格式。请参阅我关于如何应用这些服务器端的新答案。 【参考方案1】:

您正在加载一个名为 Command 的 XFDF 变体,您可以在此处查看文档。 https://www.pdftron.com/documentation/web/guides/xfdf/

以下代码是您如何加载 XFDF 命令 XML 数据并将其应用到 PDFDoc 实例。

let fdfDoc = await pdfDoc.fdfExtract(PDFNet.PDFDoc.ExtractFlag.e_both);
await fdfDoc.saveAsXFDF('data.xfdf');
fdfDoc = await PDFNet.FDFDoc.createFromXFDF('data.xfdf');
await fdfDoc.mergeAnnots(str);
await pdfDoc.fdfUpdate(fdfDoc);
await pdfDoc.refreshAnnotAppearances();

【讨论】:

@daratha-galkissa 添加了一行额外的代码,以确保为注释生成外观。 此代码有效。感谢您的帮助【参考方案2】:

默认情况下,API pdfDocument.flattenAnnotations() 只会展平 FormFields,而不是注解。 https://www.pdftron.com/api/pdfnet-node/PDFNet.PDFDoc.html#flattenAnnotations__anchor

所以我建议将调用更改为

pdfDocument.flattenAnnotations(false);

【讨论】:

以上是关于使用 NodeJs 在 Pdftron 中导入多个注释的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 ECMA 模块在 nodejs 中导入 .json 文件?

如何在 vanilla Javascript 文件中导入 nodejs 模块

使用 es6 在 NodeJs 中导入 JSON 文件

无法在nodejs中导入带有require()的模块

在nodejs中导入MySQL数据库进行集成测试的最简单方法

在 ES 模块(Node.js)中导入 JSON 文件