【问题标题】:Embed javascript in pdf with pdfkit使用 pdfkit 在 pdf 中嵌入 javascript
【发布时间】:2014-04-15 08:45:54
【问题描述】:

是否可以将一些 javascript 代码嵌入到我使用 NodeJS PDFKit (http://pdfkit.org/) 创建的 pdf 文件中?

我知道如何使用 PDFSharp 在 C# 中嵌入 javascript,当我查看 PDFSharp 创建的两个文件时,一个带有嵌入的 javascript,另一个没有它们有以下区别:

带有 javascript 的内容包含附加对象,这些对象作为最后一个对象插入:

30 0 obj
<<
/S/JavaScript
/JS(this.print\(true\); )
>>
endobj
31 0 obj
<<
/Names[(EmbeddedJS)30 0 R]
>>
endobj

在这种情况下,我嵌入的 js 是 this.print\(true\);。之后对象参考偏移也相应不同。

还有这个:

/Names
<<
/JavaScript 31 0 R
>>

pdf 的第二个对象中的引用。整个对象如下所示:

2 0 obj
<<
/Type/Catalog
/Pages 3 0 R
/Names
<<
/JavaScript 31 0 R
>>
>>
endobj

当我尝试将此代码插入到由 pdfkit 生成的 pdf 中时,我得到一个损坏的文件。有什么我想念的吗?有没有更好的方法可以使用 pdfkit 将 javascript 嵌入到 pdf 中?

PS。当然我会计算正确的对象数量,调整偏移量等。

【问题讨论】:

    标签: javascript pdf pdf-generation node-pdfkit


    【解决方案1】:

    可以在没有 JavaScript 的情况下自动触发打印:

    var ref = doc.ref({
      Type: 'Action',
      S: 'Named',
      N: 'Print'
    });
    
    doc._root.data.OpenAction = ref;
    ref.end();
    

    发件人:https://github.com/foliojs/pdfkit/issues/217#issuecomment-39281561

    【讨论】:

      【解决方案2】:

      我看到了比 PDFSharp 更直接的嵌入 JS 的方法: http://bililite.com/blog/2012/06/06/adding-javascript-to-pdf-files/

      看起来像这样:

      0 1 obj
      << 
        /Type /Catalog
        /Pages 0 2 R % a standard catalog entry
        /Names << % the Javascript entry
          /JavaScript <<
            /Names [
              (EmbeddedJS)
              <<
                /S /JavaScript
                /JS (
                  app.alert('Hello, World!');
                )
              >>
            ]
          >>
        >> % end of the javascript entry
      >>
      endobj
      

      我继续实施了一种 hacky 方式作为概念证明:

      const originalToString = Object.prototype.toString;
      Object.prototype.toString = function() {
        if (this.hasOwnProperty('rawForPdfKit')) {
          return 'hey, pdfkit, this is totally not an object, we pinky promise, please fall back to raw concatenation';
        }
        return originalToString.call(this);
      };
      
      function generatePdf() {
        const Raw = (function () {
          function Raw(rawData) {
            this.rawData = rawData;
            this.rawForPdfKit = true;
          }
          Raw.prototype.toString = function () {
            return this.rawData;
          };
          return Raw;
        }());
      
        const doc = new PdfDocument();
        const raw = new Raw(`<<
          /JavaScript <<
            /Names [
              (EmbeddedJS)
              <<
                /S /JavaScript
                /JS (
                  this.print();
                )
              >>
            ]
          >>
        >>`);
      
        doc['_root'].data.Names = raw;
      
        ...
      }
      

      强制性警告: 此方法依赖于 PDFKit 的私有 API 和实现细节,因此这可能会在 PDFKit 升级的任何时候破坏任何东西。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-05
      • 2019-12-27
      相关资源
      最近更新 更多