我正在尝试编写一个 PHP 脚本,该脚本使用pdftk http://www.accesspdf.com/pdftk/应用程序将 XFDF 与 PDF 表单合并并将合并的 PDF 输出给用户。根据pdftk文档,我可以通过via传递表单数据stdin
并将 PDF 输出到stdout
溪流。从命令行使用 pdftk 的正常、文件非流方式是:
pdftk blankform.pdf fill_form formdata.xfdf output filledform.pdf
要在命令行上使用流,您需要输入:
pdftk blankform.pdf fill_form - output -
我有几个问题:
1)我已经让 pdftk 通过返回输出stdout
使用 xfdf 文件(而不是stdin
)像这样:
exec("pdftk blankform.pdf fill_form formdata.xfdf output -", $pdf_output);
file_put_contents("filledform.pdf",$pdf_output);
但根据 Adobe Reader 的说法,它创建的 pdf 已损坏,并且使用文本编辑器快速浏览该文件表明,至少它没有将行结尾设置在应有的位置。我有一个由 pdftk 创建的相同 PDF,它输出到一个文件,并且 pdf 在文本编辑器中看起来很好,所以我知道不是 pdftk 输出了错误数据。
2)我一生都无法弄清楚如何设置stdin
PHP 中的流,以便我可以使用该流作为 pdftk 的输入。根据我在 PHP 文档中阅读的内容,stdin
是只读的,那么什么东西是如何进入该流的呢?
理想情况下,我想保持这个非常简单并避免使用proc_open()
。我尝试使用该函数,但不太成功,这可能是我的错,而不是该函数的错,但实际上我的目标很简单,我宁愿避免使用我不需要的强大函数。
理想情况下,我的代码看起来像这样:
$form_data_raw = $_POST;
$form_data_xfdf = raw2xfdf($form_data_raw); //some function that turns HTML-form data to XFDF
$blank_pdf_form = "blankform.pdf";
header('Content-type: application/pdf');
header('Content-Disposition: attachment; filename="output.pdf"');
passthru("pdftk $blank_pdf_form fill_form $form_data_xfdf output -);
请注意,可以将实际的 xml 字符串放入命令行中,但我已经very这样做的结果不可靠。
Edit
在很多帮助下,我现在明白我真正的问题是“如何将变量通过管道传输到 PHP 中的命令行执行”。显然 proc_open 是最好的方法,或者至少是最直接的方法。由于我花了很长时间才弄清楚这一点,而且我对谷歌的研究表明其他人可能会遇到困难,所以我将发布专门解决我的问题的代码:
$blank_pdf_form = "blankform.pdf";
$cmd = "pdftk $blank_pdf_form fill_form - output -";
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w")
);
$process = proc_open($cmd, $descriptorspec, $pipes);
if (is_resource($process)) {
//row2xfdf is made-up function that turns HTML-form data to XFDF
fwrite($pipes[0], raw2xfdf($_POST));
fclose($pipes[0]);
$pdf_content = stream_get_contents($pipes[1]);
fclose($pipes[1]);
$return_value = proc_close($process);
header('Content-type: application/pdf');
header('Content-Disposition: attachment; filename="output.pdf"');
echo $pdf_content;
}