大數據量導出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)