最稳当的PHP PDF生成库是tcpdf,它纯PHP实现、中文兼容好、无需系统命令,适合报表等结构化内容;需显式设置中文字体、避免输出干扰header、用ob_end_clean()清理缓冲。

用 tcpdf 生成 PDF 最稳当
PHP 原生不支持 PDF 生成,得靠第三方库。目前最成熟、中文兼容好、不用依赖系统命令的,就是 tcpdf。它纯 PHP 实现,file_get_contents 或 curl 拉来的 HTML 也能转 PDF,适合生成报表、合同、票据这类结构化内容。
安装方式(推荐 Composer):composer require tecnickcom/tcpdf
关键点:
-
TCPDF默认使用ISO-8859-1编码,直接输出中文会乱码,必须显式设置中文字体(如dejavusans或自定义simhei.php字体) - 不要用
echo或任何输出干扰 header,否则 PDF 文件头损坏,浏览器提示“文件已损坏” - 生成后建议用
ob_end_clean()清空输出缓冲,避免空白字符混入二进制流
mpdf 对 HTML/CSS 支持更友好
如果你要渲染带样式、浮动、Flex 布局的 HTML 页面为 PDF,mpdf 比 tcpdf 更省心。它对 @media print、font-face、甚至部分 CSS Grid 都有基础支持。
安装:composer require mpdf/mpdf
常见踩坑:
立即学习“PHP免费学习笔记(深入)”;
基于DEDECMS5.7 SP1制作的漂亮网络工作室整站源码,生成HTML文件。利于收录。整站采用黑色配色,彰显大气。目前仅添加新闻,案例栏目。其他类别请自行在后台添加,并修改首页模板的调用。 安装方法:1.访问:域名/install 按照提示进行安装.2.完成后登陆网站后台---还原数据库3.系统设置---修改网址和网站名称.4.生成整站,后台信息:dede后台用户名:admin后台密码:www
- 默认不加载远程图片,需开启
setHttpHeader(true)并确保allow_url_fopen = On,或改用本地路径 +base_path - 中文仍需注册字体:
$mpdf->SetFont('simhei', '', 12),字体文件(.ttf)要放在ttfonts/目录下并配置好路径 - 调用
Output()前不能有任何var_dump、print_r或未捕获的 warning,否则 PDF 解析失败
用 dompdf 快速原型但别上生产
dompdf 上手最快,require 后几行就能出 PDF,适合临时导出、内部工具。但它内存占用高、CSS 兼容弱,复杂表格或长页面容易超时或崩溃。
最小可用示例:
require_once 'vendor/autoload.php';
use Dompdf\Dompdf;
$dompdf = new Dompdf();
$dompdf->loadHtml('测试
');
$dompdf->setPaper('A4', 'portrait');
$dompdf->render();
$dompdf->stream('test.pdf');
注意:
- 不支持
position: fixed和大部分伪类(:hover,::before) - 字体嵌入不稳定,中文建议用
mbstring扩展 +set_option('default_font', 'sans') - 大文件生成慎用,
memory_limit至少设为 256M
生成 PDF 后怎么安全响应给浏览器
不是所有 Output() 调用都等价。用户下载失败,十次有八次是 header 写错了。
正确姿势(以 mpdf 为例):
- 必须在
Output()前调用header('Content-Type: application/pdf') - 文件名含中文要用
rawurlencode()编码:header('Content-Disposition: inline; filename="'.rawurlencode('订单_2024.pdf').'";') - 禁用缓存:
header('Cache-Control: no-cache, must-revalidate') - 如果走 AJAX 请求,前端要用
responseType: 'blob'接收,再用URL.createObjectURL()触发下载
最容易被忽略的是:PDF 生成过程中的警告(比如字体缺失、GD 扩展未启用)会混入二进制流,导致文件头污染。上线前务必关闭 display_errors,并用 error_log() 记录异常。










