php几十万数据导出,php 几十万数据导出到csv

参考资料 : https://blog.csdn.net/tim_phper/article/details/77581071 https://www.imooc.com/wenda/detail/316785

/**

* 下载/导出到csv文件

* @param $title 标题栏标题

* @param $data : array($count = M(表名)->where($where)->count(), $data_model = M(表名)->where($where)->order($order))

* @param $sqlLimit 单文件允许写入最大行

* @param $mark 文件名标记信息名称

* @param $func 回调函数处理查询出来的数据

*/

function downloadCsv(array $title, $data, $sqlLimit = 10000, $mark = 'test', $func = '')

{

set_time_limit(0);

$sqlCount = $data[0];

$max_line_perfile = 100000; //单文件允许写入最大行

// 输出Excel文件头,可把user.csv换成你要的文件名

header('Content-Type: application/vnd.ms-excel;charset=utf-8');

header('Content-Disposition: attachment;filename="' . $mark . '.csv' . '"');

header('Cache-Control: max-age=0');

//临时文件的删除处理

$path = "./Upload/export/" . date('Ymd');

//判断目录存在否,存在将删除目录下所有文件

if (is_dir($path)) {

rmdirr($path);

}

if (!is_dir($path)) {

//创建目录

mkdir(iconv("UTF-8", "GBK", $path), 0777, true);

}

//每次只从数据库取最大数目以防变量缓存太大

// 每隔$limit行,刷新一下输出buffer,不要太大,也不要太小

$limit = $sqlLimit;

// buffer计数器

$cnt = 0;

$fileNameArr = array();

// 逐行取出数据,不浪费内存

for ($i = 0; $i < ceil($sqlCount / $sqlLimit); $i++) {

$tmp_filename = $path . '/' . $mark . '_' . $i . '.csv';

$fp = fopen($tmp_filename, 'w'); //生成临时文件

// chmod('attack_ip_info_' . $i . '.csv',777);//修改可执行权限

$fileNameArr[] = $tmp_filename;

// 将数据通过fputcsv写到文件句柄

foreach ($title as $key => &$value) {

$value = iconv("UTF-8", "GBK", $value);

}

fputcsv($fp, $title);

$dataArr = $data[1]->limit($i * $sqlLimit, $sqlLimit)->select();

foreach ($dataArr as $a) {

if($func) { $func($a); }

//判断是否为多维数组来决定是一次写几行

if(count($a) == count($a, 1)){ //一维数组

if($sqlLimit > $max_line_perfile){

//限制一个文件不超过最大行

exit('下载单文件数目过大,请重新设置');

}

$cnt++;

if ($limit == $cnt) {

//刷新一下输出buffer,防止由于数据过多造成问题

ob_flush();

flush();

$cnt = 0;

}

fputcsv($fp, $a);

} else {

if(($sqlLimit * count($a)) > $max_line_perfile){

//限制一个文件不超过100000行

exit('下载单文件数目过大,请重新设置');

}

foreach ($a as $a_v) {

$cnt++;

if ($limit == $cnt) {

//刷新一下输出buffer,防止由于数据过多造成问题

ob_flush();

flush();

$cnt = 0;

}

fputcsv($fp, $a_v);

}

}

}

fclose($fp); //每生成一个文件关闭

}

//进行多个文件压缩

$zip = new ZipArchive();

$filename = $path . '/' . $mark . ".zip";

$zip->open($filename, ZipArchive::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=' . date('YmdHis').'_'.basename($filename)); // 文件名

header("Content-Type: application/zip"); // zip格式的

header("Content-Transfer-Encoding: binary"); //

header('Content-Length: ' . filesize($filename)); //

@readfile($filename);//输出文件;

unlink($filename); //删除压缩包临时文件

}

引用片段

$title = array("ID\t","用户名\t","币种\t","变动资金\t","剩余资金\t","日志类型\t","行为\t","日志描述\t","IP\t","产生路径\t","时间\t");

$where = preg_replace('/a\./', 'c.', $where);

$where = preg_replace('/b\./', 'd.', $where);

$data_model = M('user_coinlog as c')->join('LEFT JOIN basanyi_user as d on c.userid = d.id')->where($where)->field('d.username,c.*')->order('c.id desc');

downloadCsv($title, array($count, $data_model), 50000, 'user_trade', function(&$data){

//数据处理显示

$data['add_time'] = addtime($data['add_time']);

//排序并排除不需要的字段

$tmp_data = [];

$tmp_data[0] = $data['id'];

$tmp_data[1] = $data['username'];

$tmp_data[2] = $data['coin_name'];

$tmp_data[3] = $data['effect'];

$tmp_data[4] = $data['total'];

$tmp_data[5] = $data['log_type'];

$tmp_data[6] = iconv("UTF-8", "GBK", $data['action']);

$tmp_data[7] = iconv("UTF-8", "GBK", $data['content']);

$tmp_data[8] = $data['ip'];

$tmp_data[9] = $data['node'];

$tmp_data[10] = $data['add_time'];

$data = $tmp_data;

});

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值