推荐用 wkhtmltopdf 或 mPDF 生成 PDF:wkhtmltopdf 基于 WebKit,精准渲染 JS/CSS;mPDF 适合结构化内容,支持中文和字体嵌入;避免 dompdf,因其 CSS 支持弱、字体易乱码、内存占用高。

PHP 动态网站生成 PDF,不推荐用 dompdf 处理含大量 JS 渲染、CSS Grid/Flex 布局或字体嵌入复杂的页面——它解析 HTML 的能力有限,容易空白、乱码或超时。
用 wkhtmltopdf 命令行生成真实浏览器渲染的 PDF
这是目前最稳定、兼容性最好的方案:它基于 WebKit 内核,能准确还原 Chrome 级别的 CSS 和 JavaScript 效果。
- 需在服务器安装
wkhtmltopdf二进制(Ubuntu:`apt install wkhtmltopdf`;CentOS:用 EPEL 源或手动下载静态版) - PHP 中调用示例:
$url = 'https://yoursite.com/invoice.php?id=123';
$pdfPath = '/tmp/invoice_123.pdf';
exec("wkhtmltopdf --quiet --no-background '$url' '$pdfPath' 2>&1", $output, $returnCode);
if ($returnCode !== 0) {
error_log('wkhtmltopdf failed: ' . implode("\n", $output));
} - 关键参数:
--no-background避免打印背景色影响阅读;--quiet减少日志干扰;若需页眉页脚,用--header-html指向一个独立 HTML 片段 - 注意:URL 必须可被服务器本地访问(不能是 localhost 或 127.0.0.1,除非配置了 hosts 或改用
--allow参数放开本地路径)
用 mpdf 直接写 PHP 生成结构化 PDF(无 HTML 渲染依赖)
适合内容固定、格式可控的场景,比如发票、报表、合同模板——比 DOMPDF 更快、更省内存,且支持中文和 TrueType 字体。
- 安装:
composer require mpdf/mpdf - 基础用法:
$mpdf = new \Mpdf\Mpdf(['mode' => 'utf-8', 'format' => 'A4']);
$mpdf->WriteHTML('订单号 #123
日期:' . date('Y-m-d') . '
云枫工作室企业网站系统.net2.0下载云枫工作室企业网站源代码(.net)Version 2.0 是云枫工作室基于.net环境独立开发的一套适用于企业使用的企业网站系统。.net+access.网站使用了模板动态生成静态页面技术,前台页面是生成纯静态的。模板路径是\Themplate\skin2.熟悉html代码的朋友可以进去对模板文件进行修改(这一版的程序跟云枫工作室企业网站系统.net(蓝色版)版基本相同,只是模板风格不一样。有兴
立即学习“PHP免费学习笔记(深入)”;
');
$mpdf->Output('order_123.pdf', 'D'); - 中文字体必须显式注册:
$mpdf->autoScriptToLang = true; $mpdf->baseScript = 1; $mpdf->autoLangToFont = true;,并确保ttf文件路径正确(如 Noto Sans CJK) - 不支持
position: fixed或复杂 JS 交互,但表格分页、页码、水印、条形码(SetWatermarkText/SetBarcode)都原生可用
避免 dompdf 在生产环境踩坑的几个硬限制
很多人图方便直接上 dompdf,结果上线后 PDF 打不开、中文变方块、样式错位——不是代码写得不对,而是它的底层限制太硬。
- CSS 支持停留在 IE8 水平:不支持
flex、grid、@media print查询、calc()表达式 - 字体加载极脆弱:即使用了
@font-face,也常因路径、跨域、字体格式(.woff2 不支持)失败,最终回退到默认无衬线字体,中文直接丢失 - 内存爆炸常见于大表格:每行
都会触发 DOM 构建,1000 行可能吃掉 512MB+ 内存,导致 PHP 进程被 kill - 调试困难:错误信息只有
DOMPDF_Exception或空白 PDF,没有具体哪行 CSS/HTML 导致崩溃的提示真正要稳,就别让 PDF 生成环节承担前端渲染责任。要么用
wkhtmltopdf把渲染交给浏览器引擎,要么用mpdf放弃“所见即所得”幻想,用 PHP 逻辑控制排版——后者反而更容易测试、复用和审计。字体路径、临时文件权限、PDF 下载头里的Content-Disposition编码,这些细节比选哪个库更容易导致线上故障。 - 调试困难:错误信息只有










