在進行資料匯出的時候,少量的資料可以使用phpexcel,但大量的資料用phpexcel就很消耗資源了。
在使用fastadmin做資料匯出的時候,相關的程式碼請參考:https://blog.csdn.net/bingyu709/article/details/141949034
我自己這邊因為資料量會很大,所以程式碼層做了一個數量的劃分,少於50000走phpexcel匯出,大於50000走csv,並且打包zip。
並且我的邏輯是匯出成功後把檔案防止專案指定目錄下,並沒有做一個直接下來,如果想直接從瀏覽器下載請自己網上找其他程式碼參考,我所參考的帖子是直接下載的,大家可以試試看。
public function export() { if ($this->request->isPost()) { $filter = $this->request->request("filter", ''); $filter_arr = (array)json_decode($filter, true); $ids = $this->request->request('ids',''); $scene_id = CService::MANAGE_ALL_CUSTOMER; if (!empty($filter_arr) && isset($filter_arr['scene_id'])) { $scene_id = intval($filter_arr['scene_id']); } $scene_where = $this->getFilterAllSceneWhere($scene_id); list($where, $sort, $order, $offset, $limit) = $this->buildAllParams(); if (!empty($ids) && $ids != '' && $ids != 'all') { $ids_arr = explode(',',$ids); $where['id'] = ['in', $ids_arr]; } $where = array_merge($scene_where,$where); $count = CModel::model()->where($where)->count(); if ($count > 0) { if ($count > 50000) { set_time_limit(0); ini_set('memory_limit', '128M'); $xlsTitle = [ '欄位1', '欄位2', '欄位3' ]; // buffer計數器 $cnt = 0; $fileName = '客戶匯出'.date('YmdHis').rand(10000000,88888888);//檔名稱 $pro_path = ExportService::EXPORT_CUSTOMER_FILE_PATH; // 專案目錄 $fileName = $pro_path . $fileName; $zip_file_name = $fileName.'.zip'; // 輸出Excel檔案頭,可把user.csv換成你要的檔名 header('Content-Type: application/vnd.ms-excel;charset=utf-8'); header('Content-Disposition: attachment;filename="' . $zip_file_name . '"'); header('Cache-Control: max-age=0'); $fileNameArr = []; $every_step_limit = 10000; $loop_number_count = intval(ceil($count / $every_step_limit)); for ($i = 0; $i < $loop_number_count; $i ++) { $fp = fopen($fileName . '_' . ($i+1) . '.csv', 'w'); //生成臨時檔案 fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));/*防止亂碼 */ // chmod('attack_ip_info_' . $i . '.csv',777);//修改可執行許可權 $fileNameArr[] = $fileName . '_' . ($i+1) . '.csv'; // 將資料透過fputcsv寫到檔案控制代碼 fputcsv($fp, $xlsTitle); /******************** 調整位置開始 ***************************/ $limit = $i * $every_step_limit; $limit_list = ExportService::service()->getExportList($where, $limit, $every_step_limit); $list = ExportService::service()->formatExportData($limit_list, $this->auth_global_search_organise_id); if (!empty($list)) { foreach ($list as $item) { $cnt++; if ($limit == $cnt) { // 重新整理一下輸出buffer,防止由於資料過多造成問題 ob_flush(); flush(); $cnt = 0; } fputcsv($fp, $item); } unset($list); } fclose($fp); // 每生成一個檔案關閉 } try { // 進行多個檔案壓縮 $zip = new \ZipArchive(); $zip->open($zip_file_name, $zip::CREATE); // 開啟壓縮包 foreach ($fileNameArr as $file) { $zip->addFile($file, basename($file)); // 向壓縮包中新增檔案 } $zip->close(); // 關閉壓縮包 foreach ($fileNameArr as $file) { unlink($file); // 刪除csv臨時檔案 } if (file_exists($zip_file_name)) { $this->success('操作成功'); } else { $this->error('操作失敗'); } } catch (ValidateException|PDOException|Exception $e) { $this->error('操作失敗'); } } else { set_time_limit(0); $spreadsheet = new Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); $sheet->getStyle('A:S')->getAlignment() ->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER) //設定垂直居中 ->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER) //設定水平居中 ->setWrapText(true); //設定自動換行 $titleStyleArray = [ 'font' => [ 'name' => 'SimHei', // 中文字型,"黑體"的類似字型 'bold' => true, 'size' => 12, ] ]; $sheet->getStyle('A1:Z1')->applyFromArray($titleStyleArray); $lineStyleArray = [ 'font' => [ 'name' => 'SimHei', // 中文字型,"黑體"的類似字型 ] ]; //設定表頭 $sheet->setCellValue('A1', '欄位1'); $sheet->setCellValue('B1', '欄位2'); $sheet->setCellValue('C1', '欄位3');
....... $sheet->getColumnDimension('A')->setWidth(15); $sheet->getColumnDimension('B')->setWidth(15); $sheet->getColumnDimension('C')->setWidth(15);
.......//$sheet->getDefaultRowDimension()->setRowHeight(60); //設定行高 $res_list = ExportService::service()->getExportCustomerList($where); $list = ExportService::service()->formatExportCustomerData($res_list, $this->auth_global_search_organise_id); if (!empty($list)) { //輸出表格 foreach($list as $keys => $value) { $keys = $keys + 2; $sheet->setCellValue('A'.$keys,$value['field1'] ?? '')->getStyle('A')->applyFromArray($lineStyleArray); $sheet->setCellValue('B'.$keys,$value['field2'] ?? '')->getStyle('B')->applyFromArray($lineStyleArray); $sheet->setCellValue('C'.$keys,$value['field3'] ?? '')->getStyle('C')->applyFromArray($lineStyleArray);
.........
} } // 儲存Excel檔案到伺服器的指定路徑 $pro_path = ExportService::EXPORT_CUSTOMER_FILE_PATH; // 專案目錄 $file_name = '匯出'.date('YmdHis').rand(10000000,88888888).'.xlsx'; $file_path = $pro_path . $file_name; // if (!file_exists($file_path)) { // fopen($file_path, 'w'); // } try { $writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xlsx'); $writer->save($file_path); if (file_exists($file_path)) { $this->success('操作成功'); } else { $this->error('操作失敗'); } } catch (ValidateException|PDOException|Exception $e) { $this->error('操作失敗'); } } } } }