博主昨天在实现一个需求,因为需要用到大数据导出,所以自己动手写了一个导出方法,因为要考虑到大数据的导出,所以不能一次性读取数据库,想到了分页获取数据,写进导出缓存中,这样避免了一次性从数据库中读取大量数据而造成奔溃,思路就是分页获取数据,写进导出数组中,同时清除查询数据的缓存,这样就可以避免奔溃,下面向大家分享有关教程
博主用的是原生方法写,跟之前另一篇博客也是很相似的,大家有兴趣也可以看看(传送门) ,我们先来封装我们的数据库查询方法,等下会用,代码如下:
/**
* 获取导出数据
* @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 ();
这样我们便完成了导出上万数据而不会造成网络奔溃的方法,各位小伙伴可以尝试尝试。
更多文章请关注微信公众号