tcpdf最快上手是直接writehtml写html转pdf,支持内联css和基础标签;dompdf对复杂html兼容更好但内存占用高;fpdi用于在现有pdf模板上叠加内容;中文字体需手动配置,推荐noto sans cjk。

用 tcpdf 生成基础 PDF 最快上手
直接写 HTML 内容转 PDF 是最常见需求,tcpdf 支持内联 CSS 和基本标签(如 <h1></h1>、<table>),不用手动算坐标。安装后只需几行代码: <pre class="brush:php;toolbar:false;">require_once('tcpdf/tcpdf.php'); $pdf = new TCPDF(); $pdf->AddPage(); $pdf->writeHTML('<h2>订单详情</h2><p>编号:#ORD-2024-001</p>'); $pdf->Output('order.pdf', 'I');</pre> <p>注意:<code>Output() 第二个参数决定行为:'I' 直接浏览器打开,'D' 强制下载,'F' 保存到服务器路径。别漏掉 AddPage(),否则内容不显示。
dompdf 渲染复杂 HTML 更稳,但内存占用高
如果你的 PDF 源是现成的 HTML 页面(含 bootstrap 或 flex 布局),dompdf 兼容性更好。但它对 CSS 支持有限——position: fixed、transform 会失效,@media print 也不生效。
立即学习“PHP免费学习笔记(深入)”;
典型用法:
use DompdfDompdf; $dompdf = new Dompdf(); $dompdf->loadHtml('<style>body{font-size:14px;}</style><div>Hello</div>'); $dompdf->setPaper('A4', 'portrait'); $dompdf->render(); $dompdf->stream('hello.pdf');
关键点:setPaper() 必须在 render() 前调用;大文件容易触发 Allowed memory size exhausted,建议用 ini_set('memory_limit', '512M') 临时放宽。
需要填表单或合并已有 PDF?选 setasign/fpdi
fpdi 不是独立生成库,而是让 tcpdf 或 fpdf 能导入现有 PDF 并在其上叠加内容,适合「套打」场景(比如在预设模板上填客户姓名、金额)。
步骤分三步:
- 用
FPDI实例加载模板 PDF:$pdf->setSourceFile('template.pdf') - 用
importPage()获取某页句柄 - 用
useTemplate()将其作为背景,再用writeHTML()或Text()叠加文字
注意:fpdi 仅支持 PDF 1.4–1.7,若模板是 Acrobat Pro 导出的 PDF/X-4,会报错 Unable to find Object,需先用 Ghostscript 降级:gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -o template_v14.pdf template.pdf
中文乱码?字体配置是唯一解
所有库默认不带中文字体,直接输出中文会变方框或空白。tcpdf 需手动添加字体文件(如 simhei.php + simhei.ttf),并用 addTTFfont() 注册;dompdf 则要改配置:DompdfOptions::set('defaultFont', 'sans-serif') 并确保系统有对应字体(linux 常缺 fonts-dejavu 包)。
更省事的做法:统一用 UTF-8 编码的 Noto Sans CJK(Google 开源),它覆盖简繁日韩,且 dompdf 0.8.6+ 内置支持,只需在 HTML 中声明:<style>body{font-family:"Noto Sans CJK SC";}</style>。
生成 PDF 看似简单,但中文字体、分页断行、表格跨页、大图缩放这些细节,几乎每个项目都会卡住一两天——别指望“自动适配”,得逐项测。