dompdf 默认不支持中文,需手动配置支持 unicode 的中文字体(如 notosanscjk)、启用字体目录、设置默认字体并确保 html 编码统一为 utf-8,才能正常渲染中文文本。 如果你在使用 Dompdf(特别是 v0.8.0 及以上版本)将包含中文的 HTML 页面转换为 PDF
Dompdf正确显示中文:UTF-8与中文字体配置
时间:2026-05-28
浏览:357
文章目录

dompdf 默认不支持中文,需手动配置支持 unicode 的中文字体(如 notosanscjk)、启用字体目录、设置默认字体并确保 html 编码统一为 utf-8,才能正常渲染中文文本。
如果你在使用 Dompdf(特别是 v0.8.0 及以上版本)将包含中文的 HTML 页面转换为 PDF 时,遇到了满屏的“方块”或“□”符号,不必担心,这几乎是每位开发者都会遇到的问题。问题根源非常明确:字体缺失。Dompdf 自带的字体库(例如 DejaVu Sans)虽然支持大量 Unicode 字符,但不包含中日韩(CJK)汉字。因此,即使你的 HTML 在浏览器中显示正常,到了 PDF 渲染阶段,它也只能用“方块”来表示无法识别的汉字。
解决这个问题,本质上是一个标准的“四步走”流程。只要每一步都执行到位,中文显示问题便能迎刃而解。
正确解决方案(四步到位)
-
第一步:准备好中文字体文件
你需要一个支持 CJK 的 TrueType 字体文件。推荐使用 Google 开源的 Noto Sans CJK 系列,例如“NotoSansCJKtc-Regular.ttf”(此为繁体中文版本,简体版本同理)。下载后,将其放置到项目目录中,例如assets/fonts/。需要注意:字体文件名最好与后续代码中引用的名称保持一致(区分大小写,避免空格),这能减少许多不必要的麻烦。 -
第二步:在 PHP 代码中正确配置字体路径和默认字体
这是最关键的一步。你必须通过$options->set('fontDir', ...)明确告知 Dompdf 字体文件的存放位置。同时,使用$options->set('defaultFont', ...)设置默认字体。注意,此处填写的是字体的注册名,而非文件名。Dompdf 在首次运行时,会解析 .ttf 文件并生成对应的缓存文件(.ufm 和 .php),因此首次渲染速度会稍慢,并且需要确保指定的fontDir目录具有写入权限。 -
第三步:清理 HTML/CSS 中无效的字体声明(这一步容易被忽略)
在 HTML 的标签中编写@font-face规则尝试引入本地或远程字体,在 Dompdf v0.8.0 中基本无效。它不支持动态加载此类字体。最稳妥的做法是:直接移除 HTML 模板中所有关于@font-face的 CSS 代码,完全依赖上一步在 PHP 层配置的defaultFont。 -
第四步:确保整个流程的编码一致性
- 在 HTML 模板的
中,必须包含; - 在 PHP 端,部分老教程建议使用
mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8')进行编码转换。但对于现代框架(如 CodeIgniter 3+),只要确保$html字符串本身为 UTF-8 编码,直接使用即可,更为简洁。 - 另外,无需再手动调用
define("DOMPDF_UNICODE_ENABLED", true),因为 v0.8.0+ 版本默认已启用了 Unicode 支持。
- 在 HTML 模板的
完整可运行代码示例
将上述步骤整合后,一个完整可用的代码示例如下:
require 'assets/dompdf1/autoload.inc.php';
// 关键:指定字体目录(使用绝对路径,并确保目录可读写)
define('DOMPDF_FONT_DIR', __DIR__ . '/assets/fonts/');
$options = new Options();
$options->set('isPhpEnabled', false); // 生产环境建议关闭 PHP 内联代码解析,更安全
$options->set('fontDir', DOMPDF_FONT_DIR);
$options->set('defaultFont', 'NotoSansCJKtc-Regular'); // 注意:此处为字体注册名,非文件名
$dompdf = new Dompdf($options);
// 假设你在 CodeIgniter 框架中获取视图内容
$html = $this->load->view('view_view', $data, TRUE);
// 只要 $html 本身是 UTF-8 编码,就无需额外转换。显式声明编码更稳妥。
$dompdf->loadHtml($html, 'UTF-8');
$dompdf->setPaper('A4', 'landscape');
$dompdf->render();
$dompdf->stream('View.pdf', ['Attachment' => false]);
exit;
常见陷阱与验证步骤
配置过程中,有几个常见“陷阱”需要特别注意:
- 字体注册名 ≠ 文件名:字体文件“NotoSansCJKtc-Regular.ttf”在 Dompdf 内部的注册名通常为“NotoSansCJKtc-Regular”。如果不确定,可前往
dompdf/lib/fonts/目录,查看 Dompdf 自动生成的 .php 缓存文件来确认准确的注册名。 - 字体目录权限:如果首次运行后,在
DOMPDF_FONT_DIR目录下未看到新生成的 .ufm 或 .php 缓存文件,应首先检查该目录是否对 Web 服务器进程具有写入权限。 - 避免混合字体声明:不要在 CSS 中编写类似
font-family: 'NotoSansCJK', DejaVu Sans;的规则。Dompdf 在渲染 PDF 时,基本只认 PHP 中设置的defaultFont,其他字体家族声明会被忽略。 - 调试技巧:开启
error_reporting(E_ALL),观察是否有“Unable to load font”等错误抛出。同时,检查DOMPDF_FONT_DIR目录下是否成功生成了类似notosanscjktc-regular.ufm的文件,这是判断字体是否被成功加载和缓存的最直接证据。
完成以上配置后,Dompdf 便能清晰无误地渲染中文,方块乱码问题将彻底解决。从根本上讲,Dompdf 对中文字体的支持是一种“预加载加缓存映射”的机制,而非实时解析网络字体,因此这是一次配置、长期受益的工作。
实用工具推荐
绿化、压缩、噪点和虚拟水印,自由调节做旧程度。
选择画质和输出格式,预览压缩前后的大小。