如何通过Composer安装mpdf库轻松生成PDF文件?
- 内容介绍
- 文章标签
- 相关推荐
本文共计873个文字,预计阅读时间需要4分钟。
不是没装成功能,而是自动加载未触发展开。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.ini的memory_limit,ini_set()无效
下载 PDF 时中文文件名乱码
浏览器对 Content-Disposition 头里的中文解析不统一,IE、Edge、Chrome 各有一套逻辑,用 iconv 或 mb_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 上依然乱码。
本文共计873个文字,预计阅读时间需要4分钟。
不是没装成功能,而是自动加载未触发展开。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.ini的memory_limit,ini_set()无效
下载 PDF 时中文文件名乱码
浏览器对 Content-Disposition 头里的中文解析不统一,IE、Edge、Chrome 各有一套逻辑,用 iconv 或 mb_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 上依然乱码。

