大数据量导出excel是很常见的一个问题 php
这里给出一个方案,用到的技术为yii二、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文件 // .
建立的表格记得及时释放,表格会占用较多内存。
$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);
$zip = new ZipArchive(); if ($zip->open('excel.zip', ZipArchive::OVERWRITE) == true) { //调用方法,对要打包的根目录进行操做 addFileToZip('excel/', $zip); $zip->close(); } unset($zip)