导言:
大家都知道如果想导出大量数据到excel无论使用PHPEexcel还是他的升级版PhpSpreadsheet 都会导致内存溢出发错误,原因是phpexcel会把大量数据对象集合存入到内存中。那要如何解决呢?一般的思路都是设置php的内存的上限值,但这种方法也就是饮鸩止渴的方法,无法从根本上解决问题。而我这种方法是利用yii的batch方法来实现,每次取出固定数量的数据。啥也不说了,直接上代码。
1.导入。
a.读取大量cvs文件数据,以下方法就是可以读取大量cvs数据,利用的就是迭代生成器yield。关于yield在这里就不解释了,不懂的同学可以去百度搜索下。
/***
* 读取大数据量的cvs文件
* @param $file 需要导入的文件路径
* @return \Generator
*/
public static function readCvs($file)
{
$handle = fopen($file,'rb');
fgets($handle);
while ($data = fgetcsv($handle)){
yield $data;
}
fclose($handle);
}
b.使用方法。
$path = './test.cvs';
$data = self::readCvs($path);
//yield 会一条一条的读取数据
foreach($data as $val){
var_dump($val);
//写你的数据插入逻辑
}
2.导出
a.导出大量数据到cvs文件。
$filePath ='./test.csv';
$fp = fopen($filePath,'a');
$header_list = [["测试1","test1"],["测试2","test2"]];//头部为二维数组结构,每列都是一个数组元素,数组元素内的第一个元素为头部名称,第二个元素为数据库的字段
//写入头部文件
$head = [];
foreach ($header_list as $item) {
$head[] = iconv('utf-8', 'gbk//IGNORE', $item[0]);
}
fputcsv($fp,$head);
//mongodb 的query查询类,mysql可以按照yii的文档来,使用方法是一样的。
$query = new Query();
$query -> from([$res['db'],$res['table_name']]);
//写入数据
$query->where($where)->select($fields);
foreach ($query->batch(100,Yii::$app->$connection) as $list) {
foreach ($list as $val){
$data = [];
foreach ($header_list as $v){
$data[] = $val[$v[1]];
}
//转换成gbk编码在写入文件,这个是我自己写的编码转换方法,大家可以自己实现
fputcsv($fp,Util::arrayEncodeSet($data,'utf-8','gbk//IGNORE'));
unset($data);
}
}
fclose($fp);
$url = \Yii::$app->request->hostInfo.'/uploads/'.$fileName.'.csv'; //组装成url进行header跳转网页下载
header("Location: {$url}");
以上就是导入导出大量数据到cvs的简单实现demo,希望可以帮助到大家。