yii2 mpdf下载pdf文件配合ZipArchive压缩的性能优化和采坑经验
一、基本准备
1. 环境配置:
语言:PHP:7.0.9
服务器:Apache:2.4
框架:Yii2
2. 前提条件
项目里安装好mpdf
插件,
可以使用composer require "mpdf/mpdf": ">=7.0"
进行安装
查看mPDF官方手册
查看mPDF的GitHub
3. 业务需求
- 后台列表页面,根据搜索结果进行下载pdf文件,最终打包成压缩文件,进行下载
- 每条数据为一个pdf文件
- pdf的文件名包含中文字符(A232131-张三.pdf)
4. 采坑点及业务难点
- 往压缩文件里添加文件时
$zip->addFile($savePath. $dir_name, $dir_name)
,参数1(文件名)不得含有中文. - 解决上述问题时,当时没想着文件名用拼接的方式,一直穿,完整的再使用
iconv()
方法进行转编码,问题是可以解决,但是会非常影响性能,因为多次进行重命名.查看当时思路来源.后面会附上当时使用转编码及扫描文件的方式执行成功的代码,1000多条数据就得5分钟. - 创建
xxx.zip
文件时,使用touch($zipPath)
进行创建. 不能使用fopen($zipPath, "w")
进行创建,否则后面在执行$zip->close()
时候会无法关闭. - 压缩文件地址
$zipPath
,一开始使用静态地址,本地环境(Windows)重新生成压缩包的话,会覆盖旧的压缩文件,但是在线上(linux)环境下,会无法覆盖文件,导致每次下载,都会将旧的压缩文件地址返回.
二、业务过程
1. 第一步:将每条数据根据视图文件渲染,生成一个pdf文件,保存在服务器上
/**
* 导出pdf
*/
public function actionExportPdf()
{
set_time_limit(0);
ini_set('memory_limit', '1024M');
$this->response->format = Response::FORMAT_JSON;
$searchModelClass = $this->searchModelClass;
$searchModel = new $searchModelClass();
$params = $this->request->queryParams;
// 设置分页信息
$params['per-page'] = 50;
$params['page'] = 1;
Yii::$app->request->setQueryParams($params);
$dataProvider = $searchModel->search($this->request->queryParams);
$dataProvider->getModels();
$pages = $dataProvider->getPagination();
$pageCount = $pages->pageCount;
// pdf文件资源路径
$time = date("YmdHis", time());
$uploadPath = Yii::getAlias(Yii::$app->