因此,我的问题源于试图生成大型PDF文件,但受到PHP的内存限制/执行超时的打击,数据量太大,无法简单地扩展这些限制,因此解决方案就不成问题了。
我正在运行一个后台shell任务,该任务处理所有这些渲染,然后在PDF完成后提醒用户。
从理论上讲,我将在此外壳中包含一个循环,该循环将接收一个数据块并将其呈现给文件,然后接收下一个数据块并执行相同的操作。一旦没有要渲染的数据,该文件将被写入并完成准备提供服务。这样一来,PHP的内存限制就不会受到影响,因为只会加载可管理的块。
我目前正在使用CakePHP 3的CakePDF(v.3.5)插件(v.3.5.13),但是我一直在努力寻找一种解决方案,该解决方案可以呈现某些数据,然后将更多数据添加到同一pdf中。 有人管理过这个插件吗?还是超出了插件范围?另一个解决方案是先创建多个PDF文件,然后在创建所有单独的PDF之后将它们合并在一起吗?
这是否可行,是否有人曾经管理过,更是一个理论问题。我没有太多代码要显示,但是如果需要更多细节,请大声疾呼,我将尽力为您提供一些东西或一些示例代码!
谢谢
答案 0 :(得分:1)
这肯定超出了插件的范围,它基于将单个视图呈现到单个文件的想法而建立,该界面不支持单个文件的分块创建,如果我没记错的话,没有一个所支持的引擎确实支持,或者至少在处理大型文档时不以直接有效的方式支持。
当然有很多方法可以做到,创建多个PDF并在之后合并/合并可能是其中之一,可以分块生成源内容,然后将其传递给可以有效处理大量内容的PDF渲染器另一个,肯定还有一些库明确支持PDF的分块创建...
答案 1 :(得分:1)
我对该版本的CakePdf没有直接的经验,但是在CakePHP 2.x下,我使用wkhtmltopdf引擎,该引擎需要一个.html输出来生成PDF。
如果您的shell生成大块的.html文件,则很容易附加。 当然,wkhtmltopdf可能会在计算机上产生一些负担来生成PDF,但是由于它是二进制文件,因此它发生在PHP的内存/时间约束之外。
答案 2 :(得分:0)
我想我以后会发布我最终为任何人做的事情。
我使用CakePDF生成较小的PDF,并将其存储在tmp目录中,这些都在PHP的执行时间和内存限制的范围之内,因为我不认为更改这些内容会提供一个好的解决方案。在这一步中,我还保存了所生成的所有PDF的名称,以供下一步使用。 此代码看起来像:
while (!is_last_pdf) {
// Generate pdf in here with a portion of the data
$CakePdf = new CakePdf();
$CakePdf->template('page', 'default');
$CakePdf->viewVars(compact('data', 'other_stuff'));
// Save file name to array
$tmp_file_list[] = $file_name;
// Update the is_last_pdf variable
is_last_pdf = check_for_more_data();
}
由此,我在Shell中使用GhostScript来合并所有PDF文件,其代码如下所示:
$output_path = 'output.pdf';
$file_list = '';
// Create a string of all the files to merge
foreach ($tmp_file_list as $file) {
$file_list .= $file . ' ';
}
// Execute GhostScript to merge all the files into the `output.pdf` file
exec('gs -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -sOUTPUTFILE=' . $output_path . ' ' . $file_list);
这里的所有代码都在Shell文件中,负责创建PDF。
希望这对某人有帮助:)