使用 TCPDF 创建大型 PDF 的最有效方法是什么?
我正在努力使用 TCPDF 实施报告生成解决方案。我的一些报告很小(2-3 页),但用户可以选择一次选择许多报告,并请求所有报告。
目前,我生成一个包含所有报告的 PDF,每个报告都从一个新页面开始,并使用页面分组,以便为每个报告重新启动页码编号。当它工作时,它工作得很好,但是当我选择了太多报告后,代码就消失了,我最终得到了一个空的 PDF。
更新:我应该提到创建单个 PDF 是客户的要求。他们希望拥有一个 PDF 目录,以便在选择多个报告时能够在单个 PDF 内的报告之间轻松切换。
我的问题是:
生成此 PDF 且不会得到空白 PDF 的最有效方法是什么?我似乎找不到 TCPDF 可以处理的大小是否有限制。
我应该在 PHP 中使用 ob_start() 还是像我一样构建一个大字符串?
我的报告最初是 HTML,所以我发送该 TCPDF。但是,如果我使用其他方法输出信息(例如 Cell、MultiCell 等),TCPDF 的性能会更好吗?
这是我输出 PDF 的代码片段。 $pdf 对象是根据库中包含的相关 TCPDF 示例设置的:
foreach ($students_info as $student_info) {
$info = $student_info->fetch_object(); // get query result object
// put in the student information
$pdf->set_student_info($info->lastName, $info->firstName, $info->rank, $info->idNum);
$pdf->startPageGroup(); // start a page group to handle paging for multiple students
$pdf->AddPage(); // add a page
$html = "<style>";
$html .= file_get_contents(/*some style sheet*/);
$html .= file_get_contents(/*some other style sheet*/);
$html .= "</style>";
$html .= start_report_div($i);
$html .= '<table class="report_table">'.
'<tbody>'.
'<tr><td>';
$html .= display_report_title($report);
$html .= display_student_info($db, $info);
$html .= display_academic_comments_body($db, $info->studentID, $info->sessionID);
$html .= display_signature_block($report);
$html .= '</td></tr>'.
'</tbody>'.
'</table>';
$html .= end_report_div();
$pdf->writeHTML($html, // the content
true, // put a newline after text
false, // paint background, false = transparent
true, // reset last cell height
false, // add left padding
'' // align
);
$html = ''; // reset for next student
$pdf->lastPage(); // pointer to last page in case we are doing more than one student
}
I am working my way through implementing a report generation solution using TCPDF. Some of my reports are small (2-3 pages), but the user has the option to select many reports at once, and request them all.
Currently I generate a single PDF containing all the reports, with each report starting on a new page, and using page grouping so the page numbering is restarted for each report. When it works, it work great, but after I select too many reports, the code churns away and I end up with an empty PDF.
UPDATE: I should have mentioned that creating a single PDF is a requirement from the client. They want to have a PDF table of contents to easily switch between reports within a single PDF when they have selected many reports.
My questions are:
What is the most efficient way to produce this PDF without ending up with the blank PDF? I can't seem to find if there is a limit on the size TCPDF can handle.
Should I be using ob_start() in the PHP or is building up a big string as I am doing okay?
My reports were originally HTML, so I am sending that TCPDF. However, would TCPDF's performance be better if I used the other methods to output the info (e.g. Cell, MultiCell, etc.)?
Here is the piece of my code that outputs the PDF. The $pdf object is set up as per the relevant TCPDF examples included with the library:
foreach ($students_info as $student_info) {
$info = $student_info->fetch_object(); // get query result object
// put in the student information
$pdf->set_student_info($info->lastName, $info->firstName, $info->rank, $info->idNum);
$pdf->startPageGroup(); // start a page group to handle paging for multiple students
$pdf->AddPage(); // add a page
$html = "<style>";
$html .= file_get_contents(/*some style sheet*/);
$html .= file_get_contents(/*some other style sheet*/);
$html .= "</style>";
$html .= start_report_div($i);
$html .= '<table class="report_table">'.
'<tbody>'.
'<tr><td>';
$html .= display_report_title($report);
$html .= display_student_info($db, $info);
$html .= display_academic_comments_body($db, $info->studentID, $info->sessionID);
$html .= display_signature_block($report);
$html .= '</td></tr>'.
'</tbody>'.
'</table>';
$html .= end_report_div();
$pdf->writeHTML($html, // the content
true, // put a newline after text
false, // paint background, false = transparent
true, // reset last cell height
false, // add left padding
'' // align
);
$html = ''; // reset for next student
$pdf->lastPage(); // pointer to last page in case we are doing more than one student
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我在处理大文件和 TCPDF 时也遇到了麻烦。我从 TCPDF 切换到 mPDF。该项目基于 FPDF 和 HTML2PDF,并且通过 HTML 解析速度更快。
例如,TCPDF 需要大约 70 到 80 秒的时间来撰写文章详细信息概述(150 页,包含图片、链接和一些内容)。
相同的 HTML 代码和相同的 PHP 脚本只需替换为 mPDF 类和函数,只需 6 到 8 秒即可创建相同的 PDF。
I had trouble too with large files and TCPDF. I switched from TCPDF to mPDF. This project is based of FPDF and HTML2PDF and a lot faster with HTML-parsing.
e.g. TCPDF took for a article-detail-overview (150 pages with pictures, links and some stuff) approx 70 to 80 seconds.
The same HTML-code and the same PHP script just replaced with the mPDF-class and functions took only 6 to 8 seconds to create the same PDF.
问题1的回答:
嗯,这是我对PHP缺乏经验造成的另一个问题。空白 PDF 是由于 PHP 默认 max_execution_time 设置为 30 秒而产生的。我使用
ini_set
将 PDF 生成脚本的值设置为 300,我的报告已完整生成。对于 16 页的 PDF,生成需要 1 分 30 秒。对于拥有更多 TCPDF 经验的人来说,这是否看起来很长?
问题 3 的回答:
我已经做了一些实验,使用 TCPDF 中的直接 PDF 函数生成 PDF 肯定比将 HTML 和 CSS 传递给 TCPDF 然后让它创建 PDF 更快。有道理,但仍然很高兴看到实际的性能差异。因此,尽管为 PDF 调用创建布局很乏味,但如果您有大型 PDF,那么性能提升可能是值得的。
问题 2:
我仍然希望更有经验的 PHP 用户就 ob_start 的使用提供意见。
Answer to question 1:
Well, this is another one caused by my inexperience with PHP. The blank PDF was resulting from the default max_execution_time for PHP set to 30 sec. I used
ini_set
to set the value to 300 for the PDF generation script, and my report was generated in full.For a 16 page PDF, it took 1 min 30 sec to generate. Does that seem long to anyone with more TCPDF experience?
Answer to question 3:
I have done some experimenting, and using the direct PDF functions from TCPDF to generate the PDF is definitely faster than passing the HTML and CSS to TCPDF and then having it create the PDF. Makes sense, but still nice to see the actual performance difference. So although creating the layout for the PDF calls is tedious, if you have big PDFs, the performance gain is likely worth it.
Questions 2:
I would still appreciate input from more experienced PHP users as to the use of ob_start.