如何通过Composer安装mpdf库轻松生成PDF文件?

2026-05-06 14:471阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

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

如何通过Composer安装mpdf库轻松生成PDF文件?

不是没装成功能,而是自动加载未触发展开。Composer 安装后,必须确保项目已执行过 `composer dump-autoload`。(尤其是手动移动 vendor 或切换分支后)。Laravel/Symfony 项目通常没有问题,但纯 PHP 脚本或自建框架容易漏掉这一步。

检查方式:直接运行 php -r "var_dump(class_exists('Mpdf\Mpdf'));",输出 false 就说明 autoloader 没生效。

  • 确认 vendor/autoload.php 已被 require_once 引入,且路径正确(推荐用 __DIR__ . '/vendor/autoload.php'
  • 不要用 include 'vendor/autoload.php' —— 缺少错误提示,失败了也静默
  • 如果用了 opcache,改完 autoload 后需重启 PHP-FPM 或清空 opcache(opcache_reset()

中文显示为方块或空白

根本原因不是编码错,而是 mPDF 找不到可用的中文字体。它默认只认 DejaVuSans 这类西文字体,对 lang="zh-CN" 的 HTML 不自动 fallback。

最省事的解法是启用自动映射:

$mpdf = new MpdfMpdf([ 'autoScriptToLang' => true, 'autoLangToFont' => true ]);

但前提是你的 HTML 标签带 <html lang="zh-CN">,否则不触发。

  • 若仍报 Unable to find TTF font file,说明系统缺失基础字体,得手动配:fontDir 必须是绝对路径,fontData 中的文件名要和实际 .ttf 文件名完全一致(区分大小写)
  • 别把字体放 public/ 下——Web 可访问目录 ≠ PHP 可读目录;推荐放在 app/fonts/resources/fonts/
  • Linux 服务器上别硬塞 simhei.ttf——Windows 字体版权风险高,用开源的 NotoSansSC-Regular.ttf 更稳妥

生成大 HTML 时内存溢出或超时

mPDF 解析阶段会把整个 HTML 加载进内存做 DOM 构建,含大量内联样式、JS 或 base64 图片时极易崩。这不是 PHP 配置能简单解决的。

优先做内容瘦身:

  • ob_start() + ob_get_clean() 预处理 HTML,删掉注释、多余空格、<script> 标签
  • 所有图片必须走外链:<img src="https://example.com/a.png">,禁用 data:image/png;base64,...
  • 避免在 CSS 里用 @import 或远程字体链接,全部转成内联 style 或本地引用
  • CLI 环境跑生成任务时,加 -d memory_limit=-1;Web 环境必须改 php.inimemory_limitini_set() 无效

下载 PDF 时中文文件名乱码

浏览器对 Content-Disposition 头里的中文解析不统一,IE、Edge、Chrome 各有一套逻辑,用 iconvmb_convert_encoding 基本是碰运气。

唯一可靠方案是 RFC 5987 编码:

$filename = '发票_20260418.pdf'; header('Content-Type: application/pdf'); $header = 'Content-Disposition: attachment; filename*=UTF-8''' . rawurlencode($filename); header($header);

注意:filename* 后面是两个单引号,不是引号嵌套错误;rawurlencode() 不能换成 urlencode(),后者会把空格转成 +,RFC 不认。

这个细节极容易被忽略——很多教程只写一半,结果在 Safari 或旧版 Edge 上依然乱码。

标签:ComposerPDF

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

如何通过Composer安装mpdf库轻松生成PDF文件?

不是没装成功能,而是自动加载未触发展开。Composer 安装后,必须确保项目已执行过 `composer dump-autoload`。(尤其是手动移动 vendor 或切换分支后)。Laravel/Symfony 项目通常没有问题,但纯 PHP 脚本或自建框架容易漏掉这一步。

检查方式:直接运行 php -r "var_dump(class_exists('Mpdf\Mpdf'));",输出 false 就说明 autoloader 没生效。

  • 确认 vendor/autoload.php 已被 require_once 引入,且路径正确(推荐用 __DIR__ . '/vendor/autoload.php'
  • 不要用 include 'vendor/autoload.php' —— 缺少错误提示,失败了也静默
  • 如果用了 opcache,改完 autoload 后需重启 PHP-FPM 或清空 opcache(opcache_reset()

中文显示为方块或空白

根本原因不是编码错,而是 mPDF 找不到可用的中文字体。它默认只认 DejaVuSans 这类西文字体,对 lang="zh-CN" 的 HTML 不自动 fallback。

最省事的解法是启用自动映射:

$mpdf = new MpdfMpdf([ 'autoScriptToLang' => true, 'autoLangToFont' => true ]);

但前提是你的 HTML 标签带 <html lang="zh-CN">,否则不触发。

  • 若仍报 Unable to find TTF font file,说明系统缺失基础字体,得手动配:fontDir 必须是绝对路径,fontData 中的文件名要和实际 .ttf 文件名完全一致(区分大小写)
  • 别把字体放 public/ 下——Web 可访问目录 ≠ PHP 可读目录;推荐放在 app/fonts/resources/fonts/
  • Linux 服务器上别硬塞 simhei.ttf——Windows 字体版权风险高,用开源的 NotoSansSC-Regular.ttf 更稳妥

生成大 HTML 时内存溢出或超时

mPDF 解析阶段会把整个 HTML 加载进内存做 DOM 构建,含大量内联样式、JS 或 base64 图片时极易崩。这不是 PHP 配置能简单解决的。

优先做内容瘦身:

  • ob_start() + ob_get_clean() 预处理 HTML,删掉注释、多余空格、<script> 标签
  • 所有图片必须走外链:<img src="https://example.com/a.png">,禁用 data:image/png;base64,...
  • 避免在 CSS 里用 @import 或远程字体链接,全部转成内联 style 或本地引用
  • CLI 环境跑生成任务时,加 -d memory_limit=-1;Web 环境必须改 php.inimemory_limitini_set() 无效

下载 PDF 时中文文件名乱码

浏览器对 Content-Disposition 头里的中文解析不统一,IE、Edge、Chrome 各有一套逻辑,用 iconvmb_convert_encoding 基本是碰运气。

唯一可靠方案是 RFC 5987 编码:

$filename = '发票_20260418.pdf'; header('Content-Type: application/pdf'); $header = 'Content-Disposition: attachment; filename*=UTF-8''' . rawurlencode($filename); header($header);

注意:filename* 后面是两个单引号,不是引号嵌套错误;rawurlencode() 不能换成 urlencode(),后者会把空格转成 +,RFC 不认。

这个细节极容易被忽略——很多教程只写一半,结果在 Safari 或旧版 Edge 上依然乱码。

标签:ComposerPDF