經過上傳客戶要求主副表遷出,又提出可以將某張表的資料匯出excel,聽著很簡單,實際看資料表發現上萬條資料,並且需要關聯表查詢相關欄位,匯出的表格才可以被客戶看明白。
要是使用office包目前後臺記憶體耗盡,被迫停止執行,所以想要突破百萬條資料匯出需要另闢它路。所以就是使用了匯出CSV並非excel檔案。
1、設定程式需要一直執行並設定執行記憶體(php提示過128M)by user 悅悅 https://www.cnblogs.com/nuanai
2、資料查詢出需要匯出的資料欄位(分頁)
3、分頁進行匯出檔案並一起合併成壓縮包後下載
如果匯出前需要某些條件篩選,那就需要在前端設定表單提交篩選條件(不過多介紹)
匯出配置的編寫,需要設定檔案路徑、名稱、表頭等基本資訊 by user 悅悅 https://www.cnblogs.com/nuanai
1 //讓程式一直執行 2 set_time_limit(0); 3 //設定程式執行記憶體---php提示過128M 4 ini_set('memory_limit', '128M'); 5 //檔名使用的日期命名 6 $fileName = date('YmdHis', time()); 7 //檔案儲存位置 8 $destPath = ROOT_PATH . 'public' .DS. 'uploads'.DS.'download'.DS.$fileName. '.csv'; 9 // 開啟檔案控制代碼,準備寫入資料 10 $fileHandle = fopen($destPath, 'w'); 11 // 檢查檔案控制代碼是否成功開啟 12 if ($fileHandle === false) { 13 die('無法開啟檔案: ' . $fileHandle); 14 } 15 //表頭 16 fputcsv($fileHandle,['序號', '產品名稱', '產品型號','工名稱','條碼1','條碼2','狀態','時間']); 17 //條數 18 $nums = 10000; 19 //資料表的總數 20 $count = $this->model->count(); 21 $step = ceil($count/$nums);
查詢資料,這邊需要關聯表查詢用的是左查詢的方式,透過for迴圈進行每頁的寫入檔案
時間戳格式化直接使用了sql語句轉換,省去進入迴圈後再次迴圈格式化 by user 悅悅 https://www.cnblogs.com/nuanai
1 FROM_UNIXTIME(updatetime, '%Y-%m-%d %H:%i:%s')
需要注意就是寫入CSV之前需要對欄位轉一維陣列
1 for($i=0;$i<$step;$i++){ 2 $start = $i*$nums; 3 $result = $this->model->alias('pd') 4 ->join('products ps','ps.id=pd.product_id','LEFT') 5 ->join('step st','st.id=pd.step_id','LEFT') 6 ->field("pd.id,ps.name,ps.spec,st.name as sname,pd.barcode,pd.barnum,pd.isin,FROM_UNIXTIME(pd.updatetime, '%Y-%m-%d %H:%i:%s') AS uptime")->order("pd.updatetime","desc")->limit($start,$nums)->select(); 7 8 foreach ($result as $K=> &$item) { 9 // 轉換每行資料為一維陣列 10 $rowData = [ 11 $item['id'], 12 $item['name'], 13 $item['spec'], 14 $item['sname'], 15 $item['barcode'], 16 $item['barnum'], 17 $item['isin'], 18 $item['uptime'] 19 ]; 20 21 // 寫入 CSV 22 fputcsv($fileHandle, $rowData); 23 } 24 25 }
開啟了檔案控制代碼,記得關閉
1 // 關閉檔案控制代碼 2 fclose($fileHandle);
到這裡就是可以將上萬條資料匯出CSV檔案了,為了減少客戶下載時間,又進行了對檔案壓縮,客戶下載壓縮檔案。 by user 悅悅 https://www.cnblogs.com/nuanai
這裡使用的呼叫方法,需要傳入引數:檔名
1 if (!class_exists('ZipArchive')) { 2 throw new Exception(__('ZinArchive not install')); 3 } 4 $downloadPath = ROOT_PATH . 'public' .DS. 'uploads'.DS.'download'.DS; //伺服器中檔案zip儲存的位置 5 $destDir = $downloadPath.$zipName . '.zip'; //全路徑 6 $zip = new \ZipArchive; //壓縮類 7 $zip->open($destDir, \ZipArchive::CREATE | \ZipArchive::OVERWRITE); 8 $csvDir = $downloadPath .$csvFileName.'.csv'; //需要壓縮檔案的全路徑 9 $fileName = basename($csvDir); //獲取檔名 10 $zip->addFile($csvDir, $fileName); 11 $zip->close(); 12 $zipFilename = basename($destDir); 13 // 設定HTTP頭資訊 14 header('Content-Type: application/octet-stream'); 15 header('Content-Disposition: attachment; filename="'.$zipFilename.'"'); 16 header('Content-Length: ' . filesize($destDir)); 17 // 讀取並輸出ZIP檔案內容 18 readfile($destDir); 19 // 刪除臨時ZIP檔案(可選) 20 unlink($destDir);
這邊再生成壓縮檔案後,並刪除了雲伺服器中的壓縮檔案,如果伺服器空間允許看個人選擇;如果想要刪除伺服器中的CSV檔案,需要在生成壓縮檔案後進行刪除操作
在第一個方法的最後新增如下程式碼:儲存檔案的路徑 by user 悅悅 https://www.cnblogs.com/nuanai
1 unlink($destPath);
到這裡就可以實現客戶透過後臺進行上萬條資料的匯出下載功能了,就是有一個弊端,需要等待瀏覽器跳出下載框,哎,給客戶說一下耐心生成檔案吧。