尝试使用'fill_form'函数时,PDFtk会抛出Java异常

问题描述 投票:4回答:5

我有一个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
5个回答
10
投票

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

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

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

如果没有看到引起问题的PDF就无法回答你的问题,但是假设你的PDF包含带有/AcroForm数组的/Fields条目。在此fields数组中,有一个对字段字典的引用。假设PDF中的一个字段字典不是字典,而是PDF null对象。该表单在Adobe 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的客户软件。
  • 如果你想继续使用PdfTk,只要你不共享你想要填写的PDF文档,就不应该期待答案。

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


7
投票

事实证明,问题不在于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来填充它,通过使用模板PDF从FDF添加数据来创建新PDF,将浏览器重定向到PDFs位置。

非常感谢Bruno Lowagie帮助更好地理解系统并排除了一些事情。


3
投票

看起来PDF TK无法处理有char ()的叮咬我用\)\(取代它们以逃避它们,并且它运作良好。


0
投票

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

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

我收到了同样的错误,但是,上述解决方案都没有对我有用。

正如我测试的那样:pdftk a.pdf fill_form a.fdf output b.pdf 如果我的原始pdf没有被修改,我能够生成pdf,IE:所有默认的acrobat设置。

只有当我为fill_form元素将字体更改为“Arial”时才会收到错误。我改变了字体,它又恢复了工作。


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.