CakePHP 3 CakePDF 插件:通过循环遍历内容生成大型 PDF?
CakePHP 3 CakePDF Plugin: Generating a large PDF by looping through content?
所以我的问题源于尝试生成大型 PDF 文件,但在 PHP 中受到内存限制/执行超时的影响,数据量太大,无法简单地扩展这些限制,因此解决方案已经出局的问题。
我有一个后台 shell 任务 运行 处理所有这些渲染,然后在 PDF 完成后提醒用户。
理论上我会在这个 shell 中有一个循环,它会接收一大块数据并将其呈现到文件中,然后获取下一个数据块并执行相同的操作。一旦没有要呈现的数据,文件就会被写入并完成准备好提供服务。这样就不会达到 PHP 的内存限制,因为只会加载可管理的块。
我目前正在使用 CakePHP 3 (v.3.5.13) 的 CakePDF(v.3.5) 插件,但我正在努力寻找一个允许渲染一些数据然后添加更多数据的解决方案到同一个pdf。
之前有没有人管理过这个或者它是否超出了插件的范围?另一种解决方案是创建多个 PDF 文件,然后在创建所有单独的 PDF 后将它们合并在一起吗?
这更像是一个理论上的问题,它是否可行以及之前是否有人管理过它。我没有太多代码可以展示,但如果需要更多详细信息,请告诉我,我会尝试为您提供一些东西或一些示例代码!
谢谢
这肯定超出了插件的范围,它是围绕将单个视图呈现到单个文件的想法构建的,该界面不支持单个文件的分块创建,如果我没记错的话, none 支持的引擎也支持,至少在涉及大型文档时不是以直接有效的方式。
当然有很多方法可以做到这一点,创建多个 PDF,然后 merging/concatenating 它们可能就是其中之一,以块的形式生成源内容,并将其传递给可以处理大量文件的 PDF 渲染器content efficiently 可能是另一个,当然也可能有图书馆明确支持分块创建 PDF...
我没有使用该版本的 CakePdf 的直接经验,但在 CakePHP 2.x 下,我使用 wkhtmltopdf 引擎,它采用 .html输出以生成 PDF。
如果您的 shell 生成这样的 .html 块,则很容易追加。
当然,wkhtmltopdf 可能会给机器带来一些负载来生成 PDF,但由于它是二进制文件,它发生在 PHP 的 memory/time 限制之外。
我想我会 post 我将来为任何人所做的事情。
我使用 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);
此处的所有代码都在负责创建 PDF 的 Shell 文件中。
希望这对某人有所帮助:)
所以我的问题源于尝试生成大型 PDF 文件,但在 PHP 中受到内存限制/执行超时的影响,数据量太大,无法简单地扩展这些限制,因此解决方案已经出局的问题。
我有一个后台 shell 任务 运行 处理所有这些渲染,然后在 PDF 完成后提醒用户。
理论上我会在这个 shell 中有一个循环,它会接收一大块数据并将其呈现到文件中,然后获取下一个数据块并执行相同的操作。一旦没有要呈现的数据,文件就会被写入并完成准备好提供服务。这样就不会达到 PHP 的内存限制,因为只会加载可管理的块。
我目前正在使用 CakePHP 3 (v.3.5.13) 的 CakePDF(v.3.5) 插件,但我正在努力寻找一个允许渲染一些数据然后添加更多数据的解决方案到同一个pdf。 之前有没有人管理过这个或者它是否超出了插件的范围?另一种解决方案是创建多个 PDF 文件,然后在创建所有单独的 PDF 后将它们合并在一起吗?
这更像是一个理论上的问题,它是否可行以及之前是否有人管理过它。我没有太多代码可以展示,但如果需要更多详细信息,请告诉我,我会尝试为您提供一些东西或一些示例代码!
谢谢
这肯定超出了插件的范围,它是围绕将单个视图呈现到单个文件的想法构建的,该界面不支持单个文件的分块创建,如果我没记错的话, none 支持的引擎也支持,至少在涉及大型文档时不是以直接有效的方式。
当然有很多方法可以做到这一点,创建多个 PDF,然后 merging/concatenating 它们可能就是其中之一,以块的形式生成源内容,并将其传递给可以处理大量文件的 PDF 渲染器content efficiently 可能是另一个,当然也可能有图书馆明确支持分块创建 PDF...
我没有使用该版本的 CakePdf 的直接经验,但在 CakePHP 2.x 下,我使用 wkhtmltopdf 引擎,它采用 .html输出以生成 PDF。
如果您的 shell 生成这样的 .html 块,则很容易追加。 当然,wkhtmltopdf 可能会给机器带来一些负载来生成 PDF,但由于它是二进制文件,它发生在 PHP 的 memory/time 限制之外。
我想我会 post 我将来为任何人所做的事情。
我使用 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);
此处的所有代码都在负责创建 PDF 的 Shell 文件中。
希望这对某人有所帮助:)