大数据量导出excel是很常见的一个问题
这里给出一个方案,用到的技术为yii2、phpspreadsheet、zip
任务拆分
首先第一步需要做的就是任务拆分,将一个导出任务拆分为n个来处理
最终导出n个excel文件。
数据批获取
这一步要重点说一下,即使做了任务拆分在从数据库批获取拆分后的
数据时数据量也是很多的,这将导致php进程的内存暴增
这时就需要使用构造器、迭代器的方式来获取数据
yii2这边可以直接使用Query查询生成器的each方法来处理就行了
each就是基于迭代器的一种实现
each的思路是将查询得到的数据先临时放在数据库服务器中
在遍历迭代器的时候再分批拉取数据库服务器中的结果数据
这样就可以避免进程内存的暴增问题了
// 拆分任务
foreach($tasks as $task){
$query = Query::find();
// 遍历迭代器
foreach($query->each() as $value){
// .
// 这里拼装数据用于创建$spreadsheet
// .
}
unset($query);
// .
// 这里导出excel文件
// .
}
// .
// 这里打包所有excel文件
// .
excel导出资源释放
创建的表格记得及时释放,表格会占用较多内存。
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
// .
// 这里拼装$spreadsheet
// .
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->setPreCalculateFormulas(false);
$writer->save("**********.xlsx");
// 释放表格
$spreadsheet->disconnectWorksheets();
unset($spreadsheet);
unset($writer);
最后压缩打包导出的所有excel
$zip = new ZipArchive();
if ($zip->open('excel.zip', ZipArchive::OVERWRITE) == true) {
//调用方法,对要打包的根目录进行操作
addFileToZip('excel/', $zip);
$zip->close();
}
unset($zip)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。