讨论数量:
可以分页切片查询,比如一次1000条数据 单行追加写入cvs文件流,然后flush输出给浏览器,用户在浏览器上可以看到一直在下载, 低配服务器,单表查询7列,下载文件大小100M的csv文件下载需要 3分钟左右。
$fileName = $planId . '_' . date('YmdHis');
set_time_limit(0);
//设置程序运行内存
ini_set('memory_limit', '200M');
header('Content-Encoding: UTF-8');
header("Content-type:application/vnd.ms-excel;charset=UTF-8");
header('Content-Disposition: attachment;filename="' . $fileName . '.csv"');
//打开文件
$fp = fopen('php://output', 'a');
//添加BOM头,以UTF8编码导出CSV文件,如果文件头未添加BOM头,打开会出现乱码。
fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));
fputcsv($fp, $title);
SendLog::where('plan_id', $planId)->chunk(5000, function ($smsLogs) use ($fp) {
foreach ($smsLogs->toArray() as $v) {
if ($v['send_status'] == SmsLog::SEND_SUCCESS) {
$v['send_status'] = 'success';
} else if ($v['send_status'] == SmsLog::QUEUED_STATUS){
$v['send_status'] = 'queued';
} else {
$v['send_status'] = 'fail';
}
$exportData = [
$v['to_phone'] . "\t",
$v['username']. "\t",
];
fputcsv($fp, (array)$exportData);
}
//数据从PHP的缓冲中释放出来
ob_flush();
// 被释放出来的数据发送到浏览器
flush();
});
我感觉涉及到你说的大量,如果不使用异步导出的话,可以设置不超时,可以固定内存导出(游标读取一行一行插入,不会导致内存溢出),这些都没有问题。不过用户操作这方面就会有点不好了,用户会一直卡在这里等,一直等到导出完成,无法操作其他功能。我个人感觉大数据导出,应该用异步比较合适
推荐文章: