TCPDF中文乱码主因是未显式调用$pdf->SetFont('stsongstdlight','',14),因默认dejavusans字体不含中文字符,仅设UTF-8编码无效;HTML样式须内联、图片用绝对路径、动态数据需预处理。

中文 PDF 生成失败,90% 是字体没设对,不是编码问题,也不是模板写得不够“标准”。
TCPDF 中文乱码:为什么 setFont() 必须显式调用
TCPDF 默认字体 dejavusans 完全不包含中文字符。哪怕 HTML 是 UTF-8、new TCPDF(..., 'UTF-8', false) 也写了,只要没调 $pdf->SetFont('stsongstdlight', '', 14),中文就显示为空白或方块。
-
stsongstdlight是 TCPDF 自带的简体中文字体,Windows/macOS/Linux 均可直接用,无需额外安装 TTF 文件 - 别在 HTML 里写
style="font-family: SimSun"—— TCPDF 不解析 CSS 字体回退链,只认SetFont()当前设置的字体名 - 如果要用自定义字体(如
NotoSansCJKsc-Regular),必须先用addTTFfont()注册,且 TTF 路径需可读、文件权限正确
writeHTML() 渲染失败:HTML 写法必须“降级”
TCPDF 的 HTML 解析器不是浏览器,它不执行 JS、不支持 Flex/Grid、忽略 position: fixed,CSS 大部分失效。
- 所有样式必须内联:
class="text-center"要改成style="text-align:center;" - 表格必须加
border="1"属性,纯 CSSborder:1px solid #000不生效 - 图片路径必须是绝对路径,例如
src="/public/images/logo.png";相对路径(如./logo.png)会解析失败 - 动态数据含换行符时,先用
nl2br()转义,否则换行丢失
导出空白或 0 字节 PDF:临时目录和调试模式是隐形杀手
常见表现是浏览器返回一串乱码字符、空白页、或直接超时,但无明确错误提示。
立即学习“PHP免费学习笔记(深入)”;
- ThinkPHP 5.1+ 在调试模式下,输出缓冲可能干扰 TCPDF 的二进制流 —— 关闭调试模式(
'app_debug' => false)常能立刻解决 -
sys_get_temp_dir()在 Docker 或共享主机上常不可写,建议显式指定临时路径:$pdf->setTempDir(ROOT_PATH . 'runtime/pdf_temp/'),并确保该目录存在且权限为 755 - 若用了
exec()调wkhtmltopdf,必须确认:命令在 PATH 中、路径用escapeshellarg()包裹、临时 HTML 文件可读、PDF 输出目录可写
mpdf/dompdf/fpdf 怎么选:看你的 HTML 复杂度和部署环境
不是越新越好,也不是越重越稳。关键看谁能在你当前服务器上稳定跑通中文 + 动态内容。
-
mpdf对 HTML/CSS 支持最好,但依赖tmp/和ttfonts/目录可写,Linux 下常因权限报错:Temporary files directory ... is not writable -
dompdf需要手动加载中文字体(如simsun.ttf),还要跑load_font.php生成缓存,步骤多、容易卡在 ROOT_PATH 未定义或字体路径错 -
fpdf最轻量,但必须用iconv("utf-8","gbk", $str)转码,且所有中文都要手动处理,不适合富文本场景
真正难的不是选哪个库,而是每个库在你服务器上第一次跑通时,要同时盯住三件事:字体路径是否可读、临时目录是否可写、输出前有没有其他 echo/print_r 干扰了 header。



















