为什么要在ThinkPHP5中生成PDF
做过后台管理系统的同学一定遇到过这样的需求:把订单、报表、合同导出成PDF给用户下载。相比HTML页面,PDF格式稳定、便于打印和存档,是B端项目里的刚需。ThinkPHP5作为国内使用量极大的PHP框架,本身并没有内置PDF生成能力,但借助成熟的第三方库,实现起来非常轻松。本文就带你从零完成一个ThinkPHP5生成PDF的完整方案。
方案选型:为什么选mpdf
PHP生态里生成PDF的库主要有几个:
- TCPDF:老牌库,功能全但API繁琐,中文支持需要自己配字体。
- FPDF:轻量,但不支持UTF-8,中文基本没法用。
- Dompdf:把HTML转PDF,思路友好,但复杂CSS支持一般。
- mPDF:基于FPDF和HTML2FPDF,对HTML/CSS支持好,内置中文字体,非常适合ThinkPHP5项目。
综合考虑,本文选择mpdf/mpdf,通过Composer安装即可。它能把一段HTML直接渲染成PDF,学习成本低,中文也不会乱码。
安装mPDF
进入ThinkPHP5项目根目录,执行:
composer require mpdf/mpdf安装完成后,在vendor目录下就能看到mpdf。ThinkPHP5自带Composer自动加载,直接use即可,不需要额外配置。
基础用法:生成一个简单PDF
先在控制器里写一个最简示例,把HTML转成PDF并输出下载:
<?php
namespace app\index\controller;
use think\Controller;
use Mpdf\Mpdf;
class Pdf extends Controller
{
public function index()
{
$html = '<h1>你好,ThinkPHP5</h1><p>这是一个PDF测试文档。</p>';
$mpdf = new Mpdf([
'mode' => 'utf-8',
'format' => 'A4',
]);
$mpdf->WriteHTML($html);
// D表示直接下载,I表示浏览器预览
$mpdf->Output('demo.pdf', 'D');
}
}访问对应路由,浏览器就会下载一个名为demo.pdf的文件。中文字体mpdf会自动处理,一般不会出现方块乱码。
进阶:用模板渲染复杂内容
实际项目中PDF内容往往很长,直接拼HTML字符串很难维护。更好的做法是用ThinkPHP5的模板引擎渲染,再把结果交给mpdf。示例:
public function order($id)
{
$order = model('Order')->find($id);
if (!$order) {
$this->error('订单不存在');
}
// 用模板渲染HTML
$html = $this->fetch('pdf/order', ['order' => $order]);
$mpdf = new Mpdf([
'mode' => 'utf-8',
'format' => 'A4',
'margin_top' => 15,
'margin_bottom' => 15,
]);
// 设置页眉页脚
$mpdf->SetHTMLHeader('<div style="text-align:right;font-size:12px;">订单详情</div>');
$mpdf->SetHTMLFooter('<div style="text-align:center;font-size:12px;">第{PAGENO}页 / 共{nbpg}页</div>');
$mpdf->WriteHTML($html);
$mpdf->Output('order_' . $id . '.pdf', 'D');
}模板文件放在application/index/view/pdf/order.html,里面正常写HTML和CSS即可。mpdf支持大部分常用CSS,包括表格、边框、背景色、字体大小等,基本能满足报表类需求。
几个容易踩的坑
1. 中文乱码
如果出现中文乱码,检查两点:一是mode参数设为utf-8;二是模板文件本身保存为UTF-8无BOM格式。mpdf默认字体对中文支持有限,可以在构造参数里指定'default_font' => 'sun-exta'或使用autoScriptToLang自动识别。
2. 图片路径
mpdf读取图片时,本地绝对路径最稳妥。如果是网络图片,建议先下载到临时目录再引用,避免因权限或超时导致生成失败。
3. 大文件内存
生成几十页的PDF时,注意PHP的memory_limit。可以在生成前临时调大:
ini_set('memory_limit', '256M');4. 输出方式选择
mpdf的Output第二个参数:I为浏览器内嵌预览,D为强制下载,F为保存到服务器文件,S为返回字符串。根据业务场景灵活选择。
总结
在ThinkPHP5里生成PDF并不复杂,核心就是引入mpdf,把HTML内容交给它渲染。用模板引擎组织内容,再配合页眉页脚和输出模式,就能覆盖绝大多数业务场景。如果你正在做订单导出、报表下载或合同生成,这套方案可以直接拿去用。后续如果对性能有更高要求,可以考虑异步队列生成,避免阻塞用户请求。
评论 (0)
还没有评论,快来抢沙发吧~