博主昨天在實現一個需求,因爲需要用到大數據導出,所以自己動手寫了一個導出方法,因爲要考慮到大數據的導出,所以不能一次性讀取數據庫,想到了分頁獲取數據,寫進導出緩存中,這樣避免了一次性從數據庫中讀取大量數據而造成奔潰,思路就是分頁獲取數據,寫進導出數組中,同時清除查詢數據的緩存,這樣就可以避免奔潰,下面向大家分享有關教程
博主用的是原生方法寫,跟之前另一篇博客也是很相似的,大家有興趣也可以看看(傳送門) ,我們先來封裝我們的數據庫查詢方法,等下會用,代碼如下:
/**
* 獲取導出數據
* @param $getLinkClearSQl 數據庫語句
*/
function getReturnData($getLinkClearSQl)
{
$con = mysqli_connect("鏈接地址", "賬號名", "密碼", "數據庫名");
$getLinkClearingData = mysqli_query($con, $getLinkClearSQl);
$returnData = array();
//循環組合即將導出數據
while ($rowData = mysqli_fetch_array($getLinkClearingData)) {
$returnData[] = array(
'day' => date('Y-m-d', strtotime($rowData["day"])) . ' ',
'num1' => $rowData["num1"],
'num2' => $rowData["num2"],
'num3' => $rowData["num3"],
'num4' => $rowData["num4"],
);
}
//返回已封裝好的數據
return $returnData;
}
封裝好導出數據,然後再來封裝我們的私有方法,該方法能夠使得導出的中文不亂碼,代碼如下:
function fputcsv2($handle, array $fields, $delimiter = ",", $enclosure = '"',
$escape_char = "\\")
{
foreach ($fields as $k => $v) {
$fields[$k] = iconv("UTF-8", "GB2312//IGNORE", $v); // 這裏將UTF-8轉爲GB2312編碼
}
fputcsv($handle, $fields, $delimiter, $enclosure, $escape_char);
}
接下來是我們的主體了,上面我們已經封裝了兩個方法,跟主體區分開,看起來會比較舒服,代碼如下:
//設置時間跟最大限制
set_time_limit(0);
ini_set("memory_limit", "512M");
#設置文件名以及列名
$fileName = "導出數據";
$columnName = array('日期','字段1','字段2','字段3','字段4',);
//設置頭部
header('Content-Type: application/vnd.ms-excel;charset=utf-8');
header("Content-Disposition:filename=" . $fileName . ".csv");
// 打開PHP文件句柄,php://output 表示直接輸出到瀏覽器
$fp = fopen('php://output', 'a');
// 將中文標題轉換編碼,否則亂碼
foreach ($columnName as $i => $v) {
$columnName[$i] = $v;
}
//每次獲取數量
$pre_count = 100;
// 將標題名稱通過fputcsv寫到文件句柄
fputcsv2($fp, $columnName);
$rows = array();
//循環讀取數據並導出數據
for ($t = 0; $t < intval($linkClearingNumber / $pre_count) + 1; $t++) {
#獲取頁碼
$pageNumber = $t * $pre_count;
#重構SQL
$getLinkClearSQl = "SELECT * FROM 表名"." limit $pageNumber,$pre_count";
#獲取數據
$export_data = getReturnData($linkData, $getLinkClearSQl);
#循環獲取存放數據
foreach ($export_data as $item) {
$rows = array();
foreach ($item as $export_obj) {
$rows[] = iconv('utf-8', 'GB18030', $export_obj);
}
fputcsv($fp, $rows);
}
// 將已經寫到csv中的數據存儲變量銷燬,釋放內存佔用
unset($export_data);
ob_flush();
flush();
}
exit ();
這樣我們便完成了導出上萬數據而不會造成網絡奔潰的方法,各位小夥伴可以嘗試嘗試。