pdftk Error: Failed to open PDF file:
pdftk Error: Failed to open PDF file:
我正在使用 pdftk
库从 pdf 中提取表单字段。一切都很好 运行 除了我得到一个 pdf 文件 pdf file link 的问题。导致错误的原因如下
Error: Failed to open PDF file:
http://www.uscis.gov/sites/default/files/files/form/i-9.pdf
Done. Input errors, so no output created.
命令是
root@ri8-MS-7788:/home/ri-8# pdftk http://192.168.1.43/form/i-9.pdf dump_data_fields
同一命令适用于所有其他表单。
尝试 1
我试图将 pdf 加密为不安全的版本,但它产生了同样的错误。这是命令
pdftk http://192.168.1.43/forms/i-9.pdf input_pw foopass output /var/www/forms/un-i-9.pdf
更新
这是我处理这个问题的完整功能
public function Formanalysis($pdfname)
{
$pdffile=Yii::app()->getBaseUrl(true).'/uploads/forms/'.$pdfname;
exec("pdftk ".$pdffile." dump_data_fields 2>&1", $output,$retval);
//got an error for some pdf if these are secure
if(strpos($output[0],'Error') !== false)
{
$unsafepdf=Yii::getPathOfAlias('webroot').'/uploads/forms/un-'.$pdfname;
//echo "pdftk ".$pdffile." input_pw foopass output ".$unsafepdf;
exec("pdftk ".$pdffile." input_pw foopass output ".$unsafepdf);
exec("pdftk ".$unsafepdf." dump_data_fields 2>&1", $outputunsafe,$retval);
return $outputunsafe ;
//$response=array('0'=>'error','error'=>$output[0]);
//return $response;
}
//if (strpos($output[0],'Error') !== false){ echo "error to run" ; } // this is the option to handle error
return $output;
}
PdfTk 是通过使用 Java (GCJ) 的 GNU 编译器将 an obsolete version of iText 编译为 executable 而创建的工具(PdfTk 未被 iText Group NV 认可) .
我检查了您的 PDF,它使用了两种在创建 PdfTk 时 iText 不支持的技术:XFA 和压缩 cross-reference tables。
后者是导致您出现问题的原因。 PdfTk 希望你的文件像这样结束:
xref
0 7
0000000000 65535 f
0000000258 00000 n
0000000015 00000 n
0000000346 00000 n
0000000146 00000 n
0000000397 00000 n
0000000442 00000 n
trailer
<</ID [<c8bf0ac531b0fc7b5b9ec5daf0296834><ec4dde54d00305ebbec62f3f6bbca974>]/Root 5 0 R/Size 7/Info 6 0 R>>
%iText-5.4.3
startxref
595
%%EOF
在此代码段中,startxref
标记 xref
的字节偏移量,这是 cross-reference table 开始的位置。此 table 包含 PDF 中所有对象的 byte-offsets。
当您查看您引用的 PDF 时,您会看到它的结尾是这样的:
64 0 obj
<</DecodeParms<</Columns 5/Predictor 12>>/Encrypt 972 0 R/Filter/FlateDecode/ID[<85C47EA3EFE49E4CB0F087350055FDDC><C3F1748360D0464FBA02D711DE864630>]/Info 970 0 R/Length 283/Root 973 0 R/Size 971/Type/XRef/W[1 3 1]>>stream
hÞìÒ±JQЙ·»7J¢©ÕØ(Xþ„ù »h%¤É¤¶”€mZ+;ÁN,,ÁÆ6 XÁ&‚("î½YŒI‘Bî‡áμ]ö1Áð÷³cfþ‹ûÐÚLî`z„Ýôœùw÷N×X?ÙkNv`hÁÒj¦G[œiÀå»›œ?b½Än…ÉëàÍþ gY—i7WW‡òj®îÍ°u¸Ò‡Ñ:óÆÛ™ñÎë&'×݈§ü†ù!ÿñ€ù%,\ácçÙ9˜ì±Þ€S¼Ãd—‰Áy~×.ø¶Åìþßn_˜Ôüw£X9#åxzçgRüüóÙwÝ¡œÄNJ©½’Ú+©½’R{%µWR{%ÿ·á”;`_ z6Ø
endstream
endobj
startxref
116
%%EOF
在这种情况下,startxref
仍然指的是第一个 cross-reference table 开始的地方(它是一个线性化的 PDF),但是交叉引用 table 存储在里面一个对象,并且该对象被压缩(请参阅 stream
和 endstream
关键字之间的乱码)。
压缩 cross-reference tables 和压缩对象在 PDF 1.5 (2003) 中引入,但 PdfTk 不支持它们。您必须找到一个可以处理此类流的工具(例如,最新版本的 iText,与 PdfTk 相比,这是真正的东西),或者您必须先将 PDF 保存为 PDF 1.4,然后再使用 PdfTk 进行处理(但是你会失去 XFA,因为 XFA 也是在 PDF 1.5 中引入的)。
更新:
鉴于您询问的是表单域,我添加以下附件:
此截图是使用iText RUPS截取的(证明iText可以打开文档)。在右侧,您会看到同一个表单被定义了两次:
如果您沿着 Fields
下的树向下走,您会找到使用 AcroForm 技术存储在 PDF 中的所有字段。左边可以看到这样一个字段的描述:
如果您查看 XFA,您会注意到同样的表单也是使用 XML 表单架构定义的。如果单击 datasets
,您会在下方面板中看到数据集的 XML 描述:
所有这些信息都可以使用 iText (Java) 或 iTextSharp (C#) 以编程方式访问。 PdfTk 只是一种基于该技术的非常旧版本的工具。
这可能是一个小技巧解决方案,但应该适合您。正如@b运行o 所说,这是加密文件。在用于 pdftk
之前,您应该解密它。为此,我找到了一种解密方法,即 qpdf
一个免费的 opem 源库,用于解密 pdf、删除所有者和用户密码等等等。你可以在这里找到它 Qpdf。在您的系统上安装它。 运行 这个命令
qpdf --decrypt input.pdf output.pdf
然后在 pdftk
命令中使用输出文件。它应该工作。
我正在使用 pdftk
库从 pdf 中提取表单字段。一切都很好 运行 除了我得到一个 pdf 文件 pdf file link 的问题。导致错误的原因如下
Error: Failed to open PDF file:
http://www.uscis.gov/sites/default/files/files/form/i-9.pdf
Done. Input errors, so no output created.
命令是
root@ri8-MS-7788:/home/ri-8# pdftk http://192.168.1.43/form/i-9.pdf dump_data_fields
同一命令适用于所有其他表单。
尝试 1
我试图将 pdf 加密为不安全的版本,但它产生了同样的错误。这是命令
pdftk http://192.168.1.43/forms/i-9.pdf input_pw foopass output /var/www/forms/un-i-9.pdf
更新
这是我处理这个问题的完整功能
public function Formanalysis($pdfname)
{
$pdffile=Yii::app()->getBaseUrl(true).'/uploads/forms/'.$pdfname;
exec("pdftk ".$pdffile." dump_data_fields 2>&1", $output,$retval);
//got an error for some pdf if these are secure
if(strpos($output[0],'Error') !== false)
{
$unsafepdf=Yii::getPathOfAlias('webroot').'/uploads/forms/un-'.$pdfname;
//echo "pdftk ".$pdffile." input_pw foopass output ".$unsafepdf;
exec("pdftk ".$pdffile." input_pw foopass output ".$unsafepdf);
exec("pdftk ".$unsafepdf." dump_data_fields 2>&1", $outputunsafe,$retval);
return $outputunsafe ;
//$response=array('0'=>'error','error'=>$output[0]);
//return $response;
}
//if (strpos($output[0],'Error') !== false){ echo "error to run" ; } // this is the option to handle error
return $output;
}
PdfTk 是通过使用 Java (GCJ) 的 GNU 编译器将 an obsolete version of iText 编译为 executable 而创建的工具(PdfTk 未被 iText Group NV 认可) .
我检查了您的 PDF,它使用了两种在创建 PdfTk 时 iText 不支持的技术:XFA 和压缩 cross-reference tables。
后者是导致您出现问题的原因。 PdfTk 希望你的文件像这样结束:
xref
0 7
0000000000 65535 f
0000000258 00000 n
0000000015 00000 n
0000000346 00000 n
0000000146 00000 n
0000000397 00000 n
0000000442 00000 n
trailer
<</ID [<c8bf0ac531b0fc7b5b9ec5daf0296834><ec4dde54d00305ebbec62f3f6bbca974>]/Root 5 0 R/Size 7/Info 6 0 R>>
%iText-5.4.3
startxref
595
%%EOF
在此代码段中,startxref
标记 xref
的字节偏移量,这是 cross-reference table 开始的位置。此 table 包含 PDF 中所有对象的 byte-offsets。
当您查看您引用的 PDF 时,您会看到它的结尾是这样的:
64 0 obj
<</DecodeParms<</Columns 5/Predictor 12>>/Encrypt 972 0 R/Filter/FlateDecode/ID[<85C47EA3EFE49E4CB0F087350055FDDC><C3F1748360D0464FBA02D711DE864630>]/Info 970 0 R/Length 283/Root 973 0 R/Size 971/Type/XRef/W[1 3 1]>>stream
hÞìÒ±JQЙ·»7J¢©ÕØ(Xþ„ù »h%¤É¤¶”€mZ+;ÁN,,ÁÆ6 XÁ&‚("î½YŒI‘Bî‡áμ]ö1Áð÷³cfþ‹ûÐÚLî`z„Ýôœùw÷N×X?ÙkNv`hÁÒj¦G[œiÀå»›œ?b½Än…ÉëàÍþ gY—i7WW‡òj®îÍ°u¸Ò‡Ñ:óÆÛ™ñÎë&'×݈§ü†ù!ÿñ€ù%,\ácçÙ9˜ì±Þ€S¼Ãd—‰Áy~×.ø¶Åìþßn_˜Ôüw£X9#åxzçgRüüóÙwÝ¡œÄNJ©½’Ú+©½’R{%µWR{%ÿ·á”;`_ z6Ø
endstream
endobj
startxref
116
%%EOF
在这种情况下,startxref
仍然指的是第一个 cross-reference table 开始的地方(它是一个线性化的 PDF),但是交叉引用 table 存储在里面一个对象,并且该对象被压缩(请参阅 stream
和 endstream
关键字之间的乱码)。
压缩 cross-reference tables 和压缩对象在 PDF 1.5 (2003) 中引入,但 PdfTk 不支持它们。您必须找到一个可以处理此类流的工具(例如,最新版本的 iText,与 PdfTk 相比,这是真正的东西),或者您必须先将 PDF 保存为 PDF 1.4,然后再使用 PdfTk 进行处理(但是你会失去 XFA,因为 XFA 也是在 PDF 1.5 中引入的)。
更新:
鉴于您询问的是表单域,我添加以下附件:
此截图是使用iText RUPS截取的(证明iText可以打开文档)。在右侧,您会看到同一个表单被定义了两次:
如果您沿着 Fields
下的树向下走,您会找到使用 AcroForm 技术存储在 PDF 中的所有字段。左边可以看到这样一个字段的描述:
如果您查看 XFA,您会注意到同样的表单也是使用 XML 表单架构定义的。如果单击 datasets
,您会在下方面板中看到数据集的 XML 描述:
所有这些信息都可以使用 iText (Java) 或 iTextSharp (C#) 以编程方式访问。 PdfTk 只是一种基于该技术的非常旧版本的工具。
这可能是一个小技巧解决方案,但应该适合您。正如@b运行o 所说,这是加密文件。在用于 pdftk
之前,您应该解密它。为此,我找到了一种解密方法,即 qpdf
一个免费的 opem 源库,用于解密 pdf、删除所有者和用户密码等等等。你可以在这里找到它 Qpdf。在您的系统上安装它。 运行 这个命令
qpdf --decrypt input.pdf output.pdf
然后在 pdftk
命令中使用输出文件。它应该工作。