如何解决CodeIgniter框架下Dompdf中文显示乱码并嵌入字体?

2026-05-07 07:291阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1040个文字,预计阅读时间需要5分钟。

如何解决CodeIgniter框架下Dompdf中文显示乱码并嵌入字体?

链接文本

确认 Dompdf 字体目录路径和权限

CodeIgniter 项目里 Dompdf 的 lib/fonts/ 目录必须可读可写,否则 .ufm 字体度量文件无法自动生成,后续所有字体配置都会静默失败。

  • 检查实际路径是否为 application/third_party/dompdf/lib/fonts/(常见于手动集成)或 vendor/dompdf/dompdf/lib/fonts/(Composer 安装)
  • 把中文字体 TTF 文件(如 simhei.ttfSourceHanSansSC-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 是绝对路径(用 FCPATHrealpath()),相对路径在 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: simheiUnable to load font metric file 的警告
  • 如果 installed-fonts.dist.json 改了但没生效,确认你改的是运行时实际加载的那个文件(不是 vendor 里的只读副本)
  • 最省事的验证方式:临时把 defaultFont 设成不存在的字体名(如 'xxx'),如果 PDF 渲染直接报错,说明配置已生效;如果还静默 fallback,说明路径或初始化逻辑有问题

真正卡住人的从来不是“怎么加字体”,而是 fontDir 路径写错、.ufm 文件没生成、或者 HTML 模板里漏了 charset="UTF-8" —— 这三个点任何一个出问题,都会让前面所有操作白费。建议按顺序逐项验证,别跳步。

本文共计1040个文字,预计阅读时间需要5分钟。

如何解决CodeIgniter框架下Dompdf中文显示乱码并嵌入字体?

链接文本

确认 Dompdf 字体目录路径和权限

CodeIgniter 项目里 Dompdf 的 lib/fonts/ 目录必须可读可写,否则 .ufm 字体度量文件无法自动生成,后续所有字体配置都会静默失败。

  • 检查实际路径是否为 application/third_party/dompdf/lib/fonts/(常见于手动集成)或 vendor/dompdf/dompdf/lib/fonts/(Composer 安装)
  • 把中文字体 TTF 文件(如 simhei.ttfSourceHanSansSC-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 是绝对路径(用 FCPATHrealpath()),相对路径在 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: simheiUnable to load font metric file 的警告
  • 如果 installed-fonts.dist.json 改了但没生效,确认你改的是运行时实际加载的那个文件(不是 vendor 里的只读副本)
  • 最省事的验证方式:临时把 defaultFont 设成不存在的字体名(如 'xxx'),如果 PDF 渲染直接报错,说明配置已生效;如果还静默 fallback,说明路径或初始化逻辑有问题

真正卡住人的从来不是“怎么加字体”,而是 fontDir 路径写错、.ufm 文件没生成、或者 HTML 模板里漏了 charset="UTF-8" —— 这三个点任何一个出问题,都会让前面所有操作白费。建议按顺序逐项验证,别跳步。