excel导出百万的数据
<?php namespace app\index\controller; class Index { public function index(){ $this->excelout(); } /** * 百万级数据导出 */ public function excelout(){ //不限制执行时间,以防超时 set_time_limit(0); //文件名 $xlsName = '名字'.date('Ymd His'); //统计总行数 $sqlCount = 0; //表头 $xlsCell = ['id','姓名','年龄','des']; //对应表头的字段 $fields = 'id,name,age,des'; //统计总行数 $sqlCount = db('customer')->count(); //每次取多少条 $sqlLimit = 20000;//每次只从数据库取2000条 // buffer计数器 $cnt = 0; $fileNameArr = array(); //分段执行,以免内存写满 for ($i = 0; $i < ceil($sqlCount / $sqlLimit); $i++) { $fp = fopen($xlsName . '_' . $i . '.csv', 'w'); //生成临时文件 $fileNameArr[] = $xlsName . '_' . $i . '.csv';//将临时文件保存起来 //第一次执行时将表头写入 if($i == 0){ fputcsv($fp, $xlsCell); } //查询出数据 $xlsData = db('customer')->field($fields) ->limit($i * $sqlLimit,$sqlLimit) ->select()->toArray(); foreach ($xlsData as $k=>$v) { $cnt++; //执行下一次循环之前清空缓冲区 if ($sqlLimit == $cnt) { ob_flush(); $cnt = 0; } //每行写入到临时文件 fputcsv($fp, $v); } fclose($fp); //每生成一个文件关闭 } //将所有临时文件合并成一个 foreach ($fileNameArr as $file){ //如果是文件,提出文件内容,写入目标文件 if(is_file($file)){ $fileName = $file; //打开临时文件 $handle1 = fopen($fileName,'r'); //读取临时文件 if($str = fread($handle1,filesize($fileName))){ //关闭临时文件 fclose($handle1); //打开或创建要合并成的文件,往末尾插入的方式添加内容并保存 $handle2 = fopen($xlsName.'.csv','a+'); //写入内容 if(fwrite($handle2, $str)){ //关闭合并的文件,避免浪费资源 fclose($handle2); } } } } //将文件压缩,避免文件太大,下载慢 $zip = new \ZipArchive(); $filename = $xlsName . ".zip"; $zip->open($filename, \ZipArchive::CREATE); //打开压缩包 $zip->addFile($xlsName.'.csv', basename($xlsName.'.csv')); //向压缩包中添加文件 $zip->close(); //关闭压缩包 foreach ($fileNameArr as $file) { unlink($file); //删除csv临时文件 } //输出压缩文件提供下载 header("Cache-Control: max-age=0"); header("Content-Description: File Transfer"); header('Content-disposition: attachment; filename=' . basename($filename)); // 文件名 header("Content-Type: application/zip"); // zip格式的 header("Content-Transfer-Encoding: binary"); // header('Content-Length: ' . filesize($filename)); // @readfile($filename);//输出文件; unlink($filename); //删除压缩包临时文件 unlink($xlsName.'.csv'); //删除合并的临时文件 } public function test() { $limit = 200; $cnt = 0; $xlsTitle = ['关注时间', '微信Openid', '微信昵称', '微信头像']; set_time_limit(0); $sqlCount = db('customer')->count(); $fileName = iconv('utf-8', 'gb2312', '助力');//文件名称 $fileName = $fileName . date('_YmdHis');// 文件名称可根据自己情况设定 // 输出Excel文件头,可把user.csv换成你要的文件名 header('Content-Type: application/vnd.ms-excel;charset=utf-8'); header('Content-Disposition: attachment;filename="' . $fileName . '"'); header('Cache-Control: max-age=0'); $fileNameArr = array(); for ($i = 0; $i < ceil($sqlCount / $limit); $i++) { $fp = fopen($fileName . '_' . $i . '.csv', 'w'); //生成临时文件 // chmod('attack_ip_info_' . $i . '.csv',777);//修改可执行权限 $fileNameArr[] = $fileName . '_' . $i . '.csv'; // 将数据通过fputcsv写到文件句柄 fputcsv($fp, $xlsTitle); $start = $i * $limit; $dataArr = db('customer')->limit($start,$limit)->select(); foreach ($dataArr as $a) { $cnt++; if ($limit == $cnt) { //刷新一下输出buffer,防止由于数据过多造成问题 ob_flush(); flush(); $cnt = 0; } fputcsv($fp, $a); } fclose($fp); //每生成一个文件关闭 } //进行多个文件压缩 $zip = new \ZipArchive(); $filename = $fileName . ".zip"; $zip->open($filename, $zip::CREATE); //打开压缩包 foreach ($fileNameArr as $file) { $zip->addFile($file, basename($file)); //向压缩包中添加文件 } $zip->close(); //关闭压缩包 foreach ($fileNameArr as $file) { unlink($file); //删除csv临时文件 } //输出压缩文件提供下载 header("Cache-Control: max-age=0"); header("Content-Description: File Transfer"); header('Content-disposition: attachment; filename=' . basename($filename)); // 文件名 header("Content-Type: application/zip"); // zip格式的 header("Content-Transfer-Encoding: binary"); // header('Content-Length: ' . filesize($filename)); // @readfile($filename);//输出文件; unlink($filename); //删除压缩包临时文件 } }