【问题标题】:PDFtk throws a Java Exception when attempting to use 'fill_form' functionPDFtk 在尝试使用“fill_form”函数时抛出 Java 异常
【发布时间】:2016-08-05 11:14:45
【问题描述】:

我有一个 PHP 应用程序,它通过数据库调用填写表单。目前我正在使用 PDFtk 将其组合在一起,我能够毫无问题地运行许多 PDFtk 命令,并且我目前正在命令行上制定所需的命令。

我的电话目前是这样的:

pdftk /var/www/html/CSR/template/job_card.pdf fill_form /var/www/html/CSR/template/wwwwu7mMH.fdf output /var/www/html/CSR/template/filled4.pdf

这个确切的调用多次运行有时会产生这个错误:

    Unhandled Java Exception in create_output():
java.lang.ClassCastException: pdftk.com.lowagie.text.pdf.PdfNull cannot be cast to pdftk.com.lowagie.text.pdf.PdfDictionary
   at pdftk.com.lowagie.text.pdf.FdfReader.readFields(pdftk)
   at pdftk.com.lowagie.text.pdf.FdfReader.readPdf(pdftk)
   at pdftk.com.lowagie.text.pdf.PdfReader.<init>(pdftk)
   at pdftk.com.lowagie.text.pdf.PdfReader.<init>(pdftk)
   at pdftk.com.lowagie.text.pdf.FdfReader.<init>(pdftk)

有时会出现这个错误:

Unhandled Java Exception in create_output():
Unhandled Java Exception in main():
java.lang.NullPointerException
   at gnu.gcj.runtime.NameFinder.lookup(libgcj.so.10)
   at java.lang.Throwable.getStackTrace(libgcj.so.10)
   at java.lang.Throwable.stackTraceString(libgcj.so.10)
   at java.lang.Throwable.printStackTrace(libgcj.so.10)
   at java.lang.Throwable.printStackTrace(libgcj.so.10)

错误消息交替出现,但命令永远不会起作用并且表单永远不会被填写。正如我所说,PDFtk 可以与其他命令一起使用,我已经能够生成加密的 PDF 并成功运行固定命令。

我的问题是导致此错误的原因以及如何解决?

【问题讨论】:

    标签: java php centos6 pdftk


    【解决方案1】:

    我在 StackTrace 中看到了我的名字。这不是巧合:PdfTk 基于强大的 iText 旧版本。 iText 是一个 Java PDF 库,最初由我编写,但被第三方用于创建 PdfTk。

    错误告诉您 iText 正在解析的 PDF 存在错误或意外功能。

    PDF 由 PDF 对象组成,例如 PDF 字符串对象、PDF 数字对象、PDF 数组对象、PDF 字典对象、PDF 流对象等。 iText 能够检索这些对象并重新使用它们来创建新的 PDF。在您的情况下,会根据原始 PDF 的对象创建一个包含一些已填写表单字段的新 PDF。

    如果不查看导致问题的 PDF,就不可能回答您的问题,但假设您的 PDF 包含一个带有 /Fields 数组的 /AcroForm 条目。在这个字段数组中,有一个字段字典的引用。假设您的 PDF 中的字段字典之一不是字典,而是 PDF 空对象。表单在 Adob​​e Reader 中完美显示,但在内部,存在一个缺陷,无法正确处理表单。

    在这种情况下,iText 将遍历 fields 数组中的条目,其中一个条目不会返回字段字典,而是返回 PdfNull 对象。在这种情况下,你会得到一个ClassCastException,因为你不能将PdfNull 转换为PdfDictionary

    这就是说:

    • 如果我在您的堆栈跟踪中看到我的名字,这会触发警报,因为这意味着您正在使用早于 iText 5 的 iText 版本。不应再使用这样的版本。 You should use a more recent version of iText。更新版本的 iText 很有可能会为您提供更好的错误消息,或者容忍(甚至可能修复)PDF 中的错误。
    • 如果您发现使用更新版本 iText 的 PdfTk 版本,我会感到惊讶,因为据我所知,PdfTk 在 AGPL 下不可用,PDF Labs(PdfTk 的所有者)也不是iText Software 的客户。
    • 如果您想继续使用 PdfTk,只要您不共享您尝试填写的 PDF 文档,就不应期望得到答案。

    您可以尝试一件事:在 Adob​​e Acrobat 中打开表单。将表单保存在 Adob​​e Acrobat 中。保存的表格有可能不再有问题。 Adobe Acrobat 对 PDF 中的错误非常宽容。它试图修复尽可能多的问题。然后当你保存表单时,错误就消失了。

    【讨论】:

    • 您好 Bruno,非常感谢您抽出宝贵时间进行解释。我很高兴链接到 PDF,但听起来您非常清楚问题所在。我需要填充的表单不会更改,并且用户没有添加自己的表单的选项,因此使用不同的方法生成表单可能更容易绕过这个问题?
    • 是的。如果您共享表单,我会尝试的第一件事是:在 Adob​​e Acrobat 中打开表单。将表单保存在 Adob​​e Acrobat 中。保存的表格有可能不再有问题。 Adobe Acrobat 对 PDF 中的错误非常宽容。它试图修复尽可能多的问题。然后当你保存表单时,错误就消失了。
    • 嗨,伙计,我通过 Acrobat 运行了有问题的 PDF,但无济于事。 PDF 可在此处找到:dropbox.com/s/jyh3yz7crr4143p/job_card.pdf?dl=0 如果您能看一看,我将不胜感激。
    • 想通了,问题与 PDF 本身无关,将作为答案发布。
    【解决方案2】:

    事实证明,问题并不像 Bruno Lowagie 所建议的那样,涉及 PDF 的一致性。

    我的想法已经用完了,只是想尝试以不同的方式生成 FDF。通过运行命令:

    pdftk /full/path/to/template.pdf generate_fdf output /full/path/to/output.fdf
    

    然后检查生成的文件,我能够获得更准确的 FDF,然后当我运行 fill_form 命令时:

    pdftk /full/path/to/template.pdf fill_form /full/path/to/output.fdf output /full/path/to/output.pdf
    

    我得到了正确的回应,一切正常。所以我遇到的问题实际上是由 FDF 以某种方式格式错误引起的。

    如果有人感兴趣,我的最终解决方案是this。它需要一个带有字段的模板 PDF,生成一个 FDF 来填充它,通过将 FDF 中的数据与模板 PDF 添加来创建一个新的 PDF,将浏览器重定向到 PDF 位置。

    非常感谢 Bruno Lowagie 帮助我们更好地了解系统并排除了一些问题。

    【讨论】:

    • 谢谢你,这很有帮助,@user3192649。但是,我是否可以检查 FDF 文件是否允许在 PDF 中包含一些我想替换的字段,或者它是否必须包含 PDF 期望的每个字段?
    • 在遵循sitepoint 教程后,我也有一个格式错误的 FDF 文件,其中包含一些错误的代码。查看您的 FDF 函数向我展示了站点点代码的错误位置。
    【解决方案3】:

    看起来 PDF TK 无法处理包含 char () 的字符串,我将它们替换为 \)\( 以逃避它们,并且效果很好。

    【讨论】:

    • 谢谢!我有同样的问题,这解决了它!
    【解决方案4】:

    字体问题: https://stackoverflow.com/a/44442957/2150220

    上面的链接是一个比仅仅改变字体更好的解决方案。

    我收到了同样的错误,但是,上述解决方案都不适合我。

    在我测试时: pdftk a.pdf fill_form a.fdf output b.pdf 如果我的原始 pdf 没有被更改,我能够生成一个 pdf,即:所有默认的 acrobat 设置。

    仅当我将 fill_form 元素的字体更改为“Arial”时,我才收到错误消息。 我更改了字体,它又可以工作了。

    【讨论】:

      【解决方案5】:

      我遇到了同样的问题。在我的情况下,更改字符串编码解决了它。 以前我用 utf-8 对其进行编码,然后我将其更改为 utf_16_be。 根本原因是表单字段数据以 fdf 形式存储,其中值存储在括号内,因此如果您的数据有括号,则会引发错误。

      【讨论】:

        【解决方案6】:

        我只是想为遇到此问题的其他人跟进。在我们的例子中,问题出在 FDF 文件的内容中。具体来说,我们正在自动化填写 PDF 的过程,并且用户生成的内容有时包含未闭合的 ( [ 或 { 字符。这些会导致同样的异常。如果您发生这种情况,请确认您的 FDF 文件的内容不包含“未闭合”的括号、方括号或花括号。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-08-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-01-10
          • 1970-01-01
          相关资源
          最近更新 更多