laravel-dompdf 中文乱码的处理
背景
最近在处理 pdf 需求时使用了 laravel-dompdf 扩展包, 但是此包在默认使用场景下是不支持中文的, 会出现乱码. 因此针对此包中文乱码的处理整理如下。
参考
重点参考: dompdf 处理中文字体问题
步骤
字体处理
这一步是重点
- 我们要下载一个中文字体库 和
load_font.php,例如字体库simsun.ttf,参考文档中有。load_font.php的下载参考文档中也有。 - 将
simsum.ttf和load_font.php这两个文件,拷贝到项目的根目录,为下一步的脚本执行做准备。 - 运行如下脚本。脚本会把根目录
simsum.ttf这个字体库同步到vendor\dompdf\dompdf\lib\fonts文件夹下。php load_font.php simsun simsun.ttf
生成 PDF
字体处理完成之后,已经可以按照参考链接使用 Dompdf 示例来生成中文的 pdf 了。我这里的示例使用的是 blade 模板的形式,中间多一个 balde 转 html 过程,但是这样更利于工程化。
模板如下:
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<style>
* {
font-family: simsun, DejaVu Sans, sans-serif;
}
</style>
</head>
<body>
<p>测试展示</p>
</body>
</html>
生成 PDF 代码如下:
$dompdf = new Dompdf();
// 这里使用模板 view()->render() 得到 html
$dompdf->loadHtml(view('report')->render());
// 设置文件页面大小
$dompdf->setPaper('A4', 'landscape');
// 将 html 转为 pdf
$dompdf->render();
// 输出到浏览器
return $dompdf->stream();
// 可以存储
// Storage::put('test.pdf', $dompdf->output());
但是我们最终需要使用的是laravel-dompdf 扩展包,这个扩展包依赖 dompdf 扩展包。 使用 laravel-dompdf 扩展包来生成 PDF 的代码如下:
$pdf = Pdf::loadHTML(view('report', ['data' => $data])->render());
$pdf->save('test.pdf');
仅仅这么做,还是乱码,这是为什么呢?这是因为 laravel-dompdf 扩展包无法前面我们安装的字体库,因为这个字体库是安装到了 dompdf 扩展包的目录下,laravel-dompdf 扩展包不支持这种。我们需做如下操作。
- 加载
laravel-dompdf扩展包配置文件,生成dompdf.php的配置文件。php artisan vendor:publish --provider="Barryvdh\DomPDF\ServiceProvider" - 可以看到
dompdf.php文件中"font_dir" => storage_path('fonts')字体地址指向的是storage下的fonts文件夹下。所以我们复制前面 安装字体 时vendor\dompdf\dompdf\lib\fonts文件加下的全部字体到storage/fonts文件夹下,这种处理更有利于代码仓库管理和部署。 - 再使用前面的
laravel-dompdf扩展包的生产PDF的代码来生成 PDF 。可以看到已经支持中文正常显示了。需要注意的是我们复制字体时,需要全部字体都复制,不然还是会存在乱码,因为还需要dompdf扩展包下的其他字体。 - 此时如果你发现生成的
PDF文件过大或者生成速度慢时,可以修改dompdf.php文件。"enable_font_subsetting" => true, - 最后我们提交代码只需要提交
composer、config和storage/fonts变化的部分,前面根目录下的simsum.ttf和load_font.php这两个文件可以删除了。
本作品采用《CC 协议》,转载必须注明作者和本文链接
关于 LearnKu
推荐文章: