【问题标题】:Fill Data In Existing PDF Form Using NodeJS使用 NodeJS 在现有 PDF 表单中填写数据
【发布时间】:2017-05-10 09:08:27
【问题描述】:

问题:我有一个需要填写的现有 PDF 表单 ( *.pdf )。如何使用 Node JS 动态填充?

【问题讨论】:

  • AFAIK 此类任务的常用方法是从某个模板文件(格式为 docx、xml - 如 JasperReports - 或其他格式)中读取模板数据,并将此模板转换为 PDF,包括数据替换
  • 你检查过这个吗? pdfhummus.com
  • tks @lospejos,我会检查的!

标签: node.js pdf


【解决方案1】:

在 npm 上查看以下模块:

node-pdffiller 是 PDFtk 的包装器,PDF 工具包:

PDFKit 的网站上有很多很好的文档:

这些模块具有不同的功能和 API。你应该找到适合你需要的东西。

还有一篇不错的文章:

【讨论】:

  • 当我使用 pdffiller 的示例“generateFDFTemplate”时,出现错误“spawn pdftk ENOENT”我该如何解决?我也需要('pdfkit');
  • @M.Tae,stackoverflow.com/questions/27688804/…。对我来说太复杂了哈哈。我建议尝试其他方法。
  • 2020 年,PDFtk(PDF 工具包)很难运行。最后有一些 docker 镜像可以帮助你运行 PDFtk,但是从 NPM 模块运行 docker 镜像并不容易......
  • 如果要填写 PDF 表格,每个提到的库都有一些缺陷。库pdffillerfill-pdfnode-pdffiller (deprecated) 使用 PDFtk(我无法在 Ubuntu 18.04 上编译,在 docker 中从 NodeJS 运行很麻烦,我认为填充复选框有问题)。 pdf-fill-form 是用 C++ 编写的,它是原生 NodeJS 库(太棒了!),但不支持填充复选框:(而且 pdfkit 只是生成库(不支持表单)
  • 与 2021 年一样,这些都不起作用,有些需要下载和安装 10GB 的额外内容才能编译一个 10 行文件,这也不起作用。
【解决方案2】:

对于仍在寻找解决方案的任何人,请查看 pdf-lib (https://pdf-lib.js.org / https://www.npmjs.com/package/pdf-lib)。

有一个关于如何使用 pdf-lib Node.js 包填写 PDF 表单文本字段的好帖子:https://github.com/Hopding/pdf-lib/issues/48

【讨论】:

    【解决方案3】:

    我知道这是一个较晚的响应,但我找到了一个名为 PDF-LIB 的好库

    PDF-LIB

    功能非常丰富;

    这是一个使用它的代码示例

    const { PDFDocument } = require('pdf-lib')
    const fs = require('fs')
    const util = require('util')
    
    const data = {
      "name": "Alice Alley",
      "dateOfBirth": "01/01/1990",
      "favoriteFood": "Glue"
    }
    
    async function createPdf(input, output) {
      const readFile = util.promisify(fs.readFile)
      function getStuff() {
        return readFile(input)
      }
      const file = await getStuff()
      const pdfDoc = await PDFDocument.load(file)
      const form = pdfDoc.getForm()
      Object.keys(data).forEach((element) => {
        const field = form.getTextField(element)
        field.setText(data[element])
      })
      const pdfBytes = await pdfDoc.save()
      fs.writeFile(output, pdfBytes, () => {
        console.log('PDF created!')
      })
    }
    createPdf("input.pdf", "output.pdf")
    
    // PDF library https://pdf-lib.js.org/
    // PDF form creation https://www.pdfescape.com/

    您实际上需要在 PDF 文件中创建一个表单,然后为每个字段命名,以便使用代码引用它。

    PDF Escape

    PDF Escape 是一个网站,您可以上传 PDF,然后使用“表单域”按钮在其上创建表单... 在每个字段上右键单击并选择“对象属性...”并为您稍后将通过代码引用的字段分配一个名称,然后保存文件,下载并将其放入项目目录中。

    注意:如果您希望您的字段不可编辑并且只能由脚本填充 您需要在“对象属性...”中将字段设为“只读” 也。

    然后将输入文件名和输出名一起提供给 createPdf 函数。

    数据对象包括将键作为 PDF 文档中的字段名称,将值作为稍后要放入文档中的值。

    【讨论】:

      【解决方案4】:

      我阅读了十几个包的文档并实现了大约 5 个,唯一一个我可以在 Node JS 中满足要求并且可以从我的 MongoDB 加载远程 PDF 文件并将其填写为 pdfform.js

      更多详情here

      【讨论】:

        【解决方案5】:

        我也遇到过同样的问题,但得到了最好的解决方案,那就是 pdf-fill-form

        试试这个,感受一下它的魔力:

        var pdfFillForm = require('pdf-fill-form');
        var fs = require('fs');
        
        pdfFillForm.write('test.pdf', { "myField": "myField fill value" }, { "save": "pdf", 'cores': 4, 'scale': 0.2, 'antialias': true } )
        .then(function(result) {
            fs.writeFile("test123.pdf", result, function(err) {
                if(err) {
                    return console.log(err);
                }
                console.log("The file was saved!");
            }); 
        }, function(err) {
            console.log(err);
        });
        

        【讨论】:

        • 我需要一个独立的解决方案,它不使用像 pdfkit 这样安装的软件。
        【解决方案6】:

        node-pdftk 为我工作顺利。

        let DOCUMENTDIRECTORY = //directory holding your empty pdfs;
        
        async function producePDFs(documents, outputDirectory) {
          promises = [];
        
          for (let document of documents) {
            var fields = document["fieldsWithValue"];
            var fieldsWithValue = {};
        
            for (var i = 0; i < fields.length; i++) {
               fieldsWithValue[fields[i]["name"]] = fields[i]["value"];
            }
        
            console.log(fieldsWithValue);
        
            promises.push(
              new Promise(function (resolve, reject) {
                pdftk
                  .input(DOCUMENTDIRECTORY + document["file"]["fileName"])
                  .fillForm(fieldsWithValue)
                  .flatten()
                  .output(outputDirectory + document["file"]["fileName"])
                  .then((buffer) => {
                    getFile(outputDirectory + document["file"]["fileName"], 1000).then(
                      //1 second
                      (val) => {
                        if (val) resolve(1);
                      }
                    );
                  })
                  .catch((err) => {
                    console.log(err);
                    // handle errors
                  });
              })
            );
          }
        
          return Promise.all(promises).then(function () {
            return 1;
          });
        }
        
        async function getFile(path, time) {
          return new Promise((resolve, reject) => {
            const timeout = setInterval(function () {
              const file = path;
              const fileExists = fs.existsSync(file);
        
              console.log("Checking for: ", file);
              console.log("Exists: ", fileExists);
        
              if (fileExists) {
                clearInterval(timeout);
                resolve(1);
              }
            }, time);
          });
        }
        

        【讨论】:

        • 我正在尝试让 node-pdftk 顺利为我工作,但您的回答没有说​​明如何。
        • @Rayner 不是最漂亮的东西,但我添加了对我有用的东西。有任何问题请告诉我!
        【解决方案7】:
        const { PDFDocument } = require('pdf-lib');
        const fs = require('fs');
        const util = require('util');
        
        async function createPdf(input, output) {
          try {
            const readFile = util.promisify(fs.readFile);
            function getStuff() {
              return readFile(input);
            }
            const file = await getStuff();
            const pdfDoc = await PDFDocument.load(file);
            const form = pdfDoc.getForm();
        
            const nameField = form.getTextField('CharacterName 2');
            const ageField = form.getTextField('Age');
            const heightField = form.getTextField('Height');
            const weightField = form.getTextField('Weight');
            const eyesField = form.getTextField('Eyes');
            const skinField = form.getTextField('Skin');
            const hairField = form.getTextField('Hair');
        
            const alliesField = form.getTextField('Allies');
            const factionField = form.getTextField('FactionName');
            const backstoryField = form.getTextField('Backstory');
            const traitsField = form.getTextField('Feat+Traits');
            const treasureField = form.getTextField('Treasure');
        
            nameField.setText('Template');
            ageField.setText('24 years');
            heightField.setText(`5' 1"`);
            weightField.setText('196 lbs');
            eyesField.setText('blue');
            skinField.setText('white');
            hairField.setText('brown');
        
            // characterImageField.setImage(marioImage);
        
            alliesField.setText(
              [
                `Allies:`,
                `  • Princess Daisy`,
                `  • Princess Peach`,
                `  • Rosalina`,
                `  • Geno`,
                `  • Luigi`,
                `  • Donkey Kong`,
                `  • Yoshi`,
                `  • Diddy Kong`,
                ``,
                `Organizations:`,
                `  • Italian Plumbers Association`,
              ].join('\n')
            );
        
            factionField.setText(`Mario's Emblem`);
        
            backstoryField.setText(
              [
                `Mario is a fictional character in the Mario video game franchise, `,
                `owned by Nintendo and created by Japanese video game designer Shigeru `,
                `Miyamoto. Serving as the company's mascot and the eponymous `,
                `protagonist of the series, Mario has appeared in over 200 video games `,
                `since his creation. Depicted as a short, pudgy, Italian plumber who `,
                `resides in the Mushroom Kingdom, his adventures generally center `,
                `upon rescuing Princess Peach from the Koopa villain Bowser. His `,
                `younger brother and sidekick is Luigi.`,
              ].join('\n')
            );
        
            traitsField.setText(
              [
                `Mario can use three basic three power-ups:`,
                `  • the Super Mushroom, which causes Mario to grow larger`,
                `  • the Fire Flower, which allows Mario to throw fireballs`,
                `  • the Starman, which gives Mario temporary invincibility`,
              ].join('\n')
            );
        
            treasureField.setText(['• Gold coins', '• Treasure chests'].join('\n'));
        
            const pdfBytes = await pdfDoc.save();
            fs.writeFile(output, pdfBytes, () => {
              console.log('PDF created!');
            });
          } catch (err) {
            console.log(err);
          }
        }
        createPdf('input.pdf', 'output.pdf');
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-11-05
          • 1970-01-01
          • 2017-08-21
          • 1970-01-01
          • 2020-12-11
          • 1970-01-01
          相关资源
          最近更新 更多