如何解决CodeIgniter框架下Dompdf中文显示乱码并嵌入字体?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1040个文字,预计阅读时间需要5分钟。
链接文本
确认 Dompdf 字体目录路径和权限
CodeIgniter 项目里 Dompdf 的 lib/fonts/ 目录必须可读可写,否则 .ufm 字体度量文件无法自动生成,后续所有字体配置都会静默失败。
- 检查实际路径是否为
application/third_party/dompdf/lib/fonts/(常见于手动集成)或vendor/dompdf/dompdf/lib/fonts/(Composer 安装) - 把中文字体 TTF 文件(如
simhei.ttf或SourceHanSansSC-Regular.otf)直接丢进该目录 - 执行一次
chmod -R 755 lib/fonts/(Linux/macOS)或确保 Windows 下 IIS/Apache 用户有读取+写入权限 - 别跳过验证:生成 PDF 后去
lib/fonts/看有没有对应名称的.ufm文件(例如simhei.ufm),没有就说明字体没被识别
在 CodeIgniter 中正确初始化 Dompdf 并设置 defaultFont
很多乱码问题出在 CodeIgniter 的 autoloader 和 Dompdf 初始化时机上——defaultFont 必须在 new Dompdf() 前设好,且不能依赖全局配置文件。
- 不要在
config/dompdf.php里设defaultFont(Dompdf 不读这个) - 在控制器或库中显式传参:
$options = new \Dompdf\Options(); $options->set('fontDir', FCPATH . 'application/third_party/dompdf/lib/fonts/'); $options->set('defaultFont', 'simhei'); $dompdf = new \Dompdf\Dompdf($options);
- 确保
fontDir是绝对路径(用FCPATH或realpath()),相对路径在 CLI 或子目录下极易失效 - 如果用了 Composer,路径可能是
vendor/dompdf/dompdf/lib/fonts/,别硬写成dompdf/lib/fonts/
HTML 模板里的编码与 CSS 字体声明必须同步
即使字体和 PHP 配置全对,HTML 模板里一个 <meta charset="GBK"> 就能让中文变方块。Dompdf 对 HTML 解析非常严格。
- 模板开头必须是:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <style> body { font-family: "simhei", sans-serif; } </style> </head>
-
loadHtml()调用时第二个参数必须显式指定编码:$dompdf->loadHtml($html, 'UTF-8');
- CSS 中的
font-family值要和installed-fonts.dist.json里注册的 key 一致(比如注册的是"simhei",就不能写"SimHei"或"微软雅黑") - 避免在 HTML 里用
XXXX;实体代替中文——Dompdf 的 HTML5 解析器对某些实体支持不稳,直接写 UTF-8 字符最可靠
调试时优先看 .ufm 文件和 debug 日志
Dompdf 不报错 ≠ 正常工作。它经常默默 fallback 到默认字体(DejaVuSans),导致中文显示为空白或小方块,而你完全看不到错误提示。
- 启用调试模式:
$options->set('debugCss', true); $options->set('debugLayout', true); $options->set('debugKeepTemp', true);生成的临时 HTML 和 CSS 文件会保留在系统临时目录,打开就能看到 Dompdf 实际解析出的字体名
- 检查日志里有没有类似
Font not found: simhei或Unable to load font metric file的警告 - 如果
installed-fonts.dist.json改了但没生效,确认你改的是运行时实际加载的那个文件(不是 vendor 里的只读副本) - 最省事的验证方式:临时把
defaultFont设成不存在的字体名(如'xxx'),如果 PDF 渲染直接报错,说明配置已生效;如果还静默 fallback,说明路径或初始化逻辑有问题
真正卡住人的从来不是“怎么加字体”,而是 fontDir 路径写错、.ufm 文件没生成、或者 HTML 模板里漏了 charset="UTF-8" —— 这三个点任何一个出问题,都会让前面所有操作白费。建议按顺序逐项验证,别跳步。
本文共计1040个文字,预计阅读时间需要5分钟。
链接文本
确认 Dompdf 字体目录路径和权限
CodeIgniter 项目里 Dompdf 的 lib/fonts/ 目录必须可读可写,否则 .ufm 字体度量文件无法自动生成,后续所有字体配置都会静默失败。
- 检查实际路径是否为
application/third_party/dompdf/lib/fonts/(常见于手动集成)或vendor/dompdf/dompdf/lib/fonts/(Composer 安装) - 把中文字体 TTF 文件(如
simhei.ttf或SourceHanSansSC-Regular.otf)直接丢进该目录 - 执行一次
chmod -R 755 lib/fonts/(Linux/macOS)或确保 Windows 下 IIS/Apache 用户有读取+写入权限 - 别跳过验证:生成 PDF 后去
lib/fonts/看有没有对应名称的.ufm文件(例如simhei.ufm),没有就说明字体没被识别
在 CodeIgniter 中正确初始化 Dompdf 并设置 defaultFont
很多乱码问题出在 CodeIgniter 的 autoloader 和 Dompdf 初始化时机上——defaultFont 必须在 new Dompdf() 前设好,且不能依赖全局配置文件。
- 不要在
config/dompdf.php里设defaultFont(Dompdf 不读这个) - 在控制器或库中显式传参:
$options = new \Dompdf\Options(); $options->set('fontDir', FCPATH . 'application/third_party/dompdf/lib/fonts/'); $options->set('defaultFont', 'simhei'); $dompdf = new \Dompdf\Dompdf($options);
- 确保
fontDir是绝对路径(用FCPATH或realpath()),相对路径在 CLI 或子目录下极易失效 - 如果用了 Composer,路径可能是
vendor/dompdf/dompdf/lib/fonts/,别硬写成dompdf/lib/fonts/
HTML 模板里的编码与 CSS 字体声明必须同步
即使字体和 PHP 配置全对,HTML 模板里一个 <meta charset="GBK"> 就能让中文变方块。Dompdf 对 HTML 解析非常严格。
- 模板开头必须是:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <style> body { font-family: "simhei", sans-serif; } </style> </head>
-
loadHtml()调用时第二个参数必须显式指定编码:$dompdf->loadHtml($html, 'UTF-8');
- CSS 中的
font-family值要和installed-fonts.dist.json里注册的 key 一致(比如注册的是"simhei",就不能写"SimHei"或"微软雅黑") - 避免在 HTML 里用
XXXX;实体代替中文——Dompdf 的 HTML5 解析器对某些实体支持不稳,直接写 UTF-8 字符最可靠
调试时优先看 .ufm 文件和 debug 日志
Dompdf 不报错 ≠ 正常工作。它经常默默 fallback 到默认字体(DejaVuSans),导致中文显示为空白或小方块,而你完全看不到错误提示。
- 启用调试模式:
$options->set('debugCss', true); $options->set('debugLayout', true); $options->set('debugKeepTemp', true);生成的临时 HTML 和 CSS 文件会保留在系统临时目录,打开就能看到 Dompdf 实际解析出的字体名
- 检查日志里有没有类似
Font not found: simhei或Unable to load font metric file的警告 - 如果
installed-fonts.dist.json改了但没生效,确认你改的是运行时实际加载的那个文件(不是 vendor 里的只读副本) - 最省事的验证方式:临时把
defaultFont设成不存在的字体名(如'xxx'),如果 PDF 渲染直接报错,说明配置已生效;如果还静默 fallback,说明路径或初始化逻辑有问题
真正卡住人的从来不是“怎么加字体”,而是 fontDir 路径写错、.ufm 文件没生成、或者 HTML 模板里漏了 charset="UTF-8" —— 这三个点任何一个出问题,都会让前面所有操作白费。建议按顺序逐项验证,别跳步。

