tcpdf最稳但需v6.6.5+兼容php8.2,dompdf须v2.0.4+并正确配置中文字体、缓冲清空及http头,复杂表格宜用tcpdf原生单元格绘制。

用 tcpdf 生成 PDF 最稳,但要注意 PHP8.2 的构造函数兼容性
PHP8.2 严格了构造函数签名,而老版本 TCPDF(如 6.2.x)在 __construct() 中参数顺序或默认值不匹配会导致 Fatal error。必须用 tcpdf/tcpdf v6.6.5+ 或直接切到更现代的替代方案。
实操建议:
- 优先执行
composer require tecnickcom/tcpdf:~6.6.5,避免用已归档的tecnickcom/tcpdf旧分支 - 若项目已用
dompdf/dompdf,需升级到 v2.0.4+,否则DOMDocument::loadHTML()在 PHP8.2 下会因弃用警告触发致命错误 - 不要手动 new TCPDF() 后再 setXXX()——PHP8.2 对 protected 属性写入更敏感,应一次性传参初始化
dompdf 导出中文 PDF 必须配字体和编码,否则全是方块
DOMPDF 默认不支持 UTF-8 中文,不是加个 mb_convert_encoding() 就能解决的。核心是字体注册 + HTML 声明 + PDF 渲染上下文三者对齐。
实操建议:
- 下载 NotoSansCJKsc 或 simsun.ttc 字体文件,放进
vendor/dompdf/dompdf/lib/fonts/目录 - 运行
vendor/bin/dompdf_font_converter.php simsun.ttc simsun生成 PHP 字体描述文件 - PHP 中调用前必须设置:
Dompdf\Options::set('defaultFont', 'simsun'),且 HTML 中<meta charset="UTF-8">不可少 - 避免在 HTML 里用
style="font-family: 'Microsoft YaHei'"—— DOMPDF 不识别系统字体名,只认注册过的字体别名
导出时浏览器乱码或提示损坏?检查 Content-Disposition 和输出缓冲
PHP8.2 默认开启 output_buffering=on,而 PDF 是二进制流,任何前置空格、BOM、echo 都会让文件头失效,导致 Chrome 提示“无法打开 PDF”或 Adobe 显示损坏。
实操建议:
- 导出前强制清空并关闭缓冲:
ob_end_clean();,而不是ob_flush()或flush() - Header 必须按顺序且完整:
header('Content-Type: application/pdf');→header('Content-Length: ' . strlen($pdf->output('', 'S')));→header('Content-Disposition: inline; filename="report.pdf"'); - 最后必须用
echo $pdf->output('', 'S');,不能用write()或stream()—— 后两者会自动 send headers,和你手动设的冲突
大表格或分页崩溃?别硬塞 HTML,改用 tcpdf 原生单元格绘制
DOMPDF 渲染复杂 HTML 表格(尤其带 colspan/rowspan 或大量数据)极易内存溢出或超时;tcpdf 的 writeHTML() 也一样。真要稳定,就得绕开 HTML 解析层。
实操建议:
- 用
$pdf->AddPage()+$pdf->SetXY()定位,再用$pdf->Cell()逐行画表,控制宽度/高度/边框/换行 - 中文换行用
$pdf->writeHTMLCell()并设$ln = 1,别依赖 CSS white-space - 分页逻辑自己判断:每写 30 行就
$pdf->AddPage(),比等 DOMPDF 自动分页可靠得多
真正麻烦的不是生成 PDF,而是确保从字体加载、缓冲控制到 HTTP 头全程零干扰。PHP8.2 对输出一致性的要求比以前高得多,一个 var_dump() 落在导出流程前面,整个 PDF 就废了。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











