對於做后台開發的碼農來說,從excel導入數據到數據庫亦或者是從數據庫導出數據到excel都是很常見的操作。由於經常遇到這樣的場景,也因為從數據庫導出數據到表格所遇到的坑有很多,所以需要另辟途徑來進行這種場景優化。
如果是小量的數據導出到excel的表格的話,一般不會有太多效率和資源占用的問題,但是當數據量變得龐大了,例如20萬或者50萬的時候就會造成PHP處理的瓶頸,要么內存溢出要么腳本運行超時。當然PHP是相對於比較靈活的,大可在方法運行的時候單獨更改超時時間和腳本運行內存。但是這都是於事無補的,一般xls的格式最大支持六萬行的數據左右,所以到了六萬行的時候就涼涼了。
后續查閱資料發現csv是可以支持無限行數的,只要你的電腦能支持打開就能不斷的往里面塞數據。
CSV格式文件最大行數是沒有上限的,在國外科學數據網站下載的CSV文件有幾十G上百G,行數多大幾十億上百億行;但是大文件CSV打開編輯的軟件就基本沒有,Excel、wps、openoffice緊支持打開編輯前面1048576行;snapde軟件支持的行數多一些,一次可以打開編輯一兩千萬行的CSV數據,速度超快。
代碼
<?php
public function exportWarehouseManagementToExcel()
{
ini_set('max_execution_time', 300);// 設置PHP超時時間
ini_set('memory_limit', '2048M');// 設置PHP臨時允許內存大小
$querySql = "SELECT * FROM fsyz_cpInventory WHERE 1=1";//導出所有的數據
$queryResult = $this->db->query($querySql)->result_array();
//路徑
$fileName = '車管駐點業務寄遞倉庫管理所有數據' . date('Ymd_His') . '.csv';
$filePath = 'excel/' . $fileName;
$index = 0;
$fp = fopen($filePath, 'w'); //生成臨時文件
chmod($filePath, 0777);//修改可執行權限
// 將數據通過fputcsv寫到文件句柄
$header = array('車牌號碼', '車牌類型', '所在區域', '狀態', '入庫時間');//設置表頭
fputcsv($fp, $header);
//處理導出數據
foreach ($queryResult as $key => &$val) {
foreach ($val as $k => $v) {
$val[$k] = $v . "\t";
if ($index == 10000) { //每次寫入1000條數據清除內存
$index = 0;
ob_flush();//清除內存
flush();
}
$index++;
}
fputcsv($fp, $val);
}
ob_flush();
fclose($fp); //關閉句柄
header("Cache-Control: max-age=0");
header("Content-type:application/vnd.ms-excel;charset=UTF-8");
header("Content-Description: File Transfer");
header('Content-disposition: attachment; filename=' . basename($fileName));
header("Content-Type: text/csv");
header("Content-Transfer-Encoding: binary");
header('Content-Length: ' . filesize($filePath));
@readfile($filePath);//輸出文件;
unlink($filePath); //刪除壓縮包臨時文件
echo $filePath;
return;
}
轉載: