文档章节

php 几十万数据导出到csv

病态S
 病态S
发布于 09/04 17:43
字数 838
阅读 23
收藏 0
PHP

参考资料 : 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;
            });

 

本文转载自:https://blog.csdn.net/tim_phper/article/details/77581071

共有 人打赏支持
病态S
粉丝 1
博文 84
码字总数 36001
作品 0
程序员
私信 提问
magento系统自带批量小结

接触magento也快2个月了,由什么都不知道的小白----------到能够独立搭建网站---------到独立写一点属性的代码,其中有苦也有甜,有时候为了一个简单了问题你可能要奋战到深夜,但是现在想想...

发疯的黑蜗牛
2013/08/30
0
2
发现很多PHP的程序瓶颈都是和Mysql应用上

最近手上有好多台VPS,你懂的。 然后闲着不能浪费,就在上面做了定时任务,找一些网上的网站、博客之类的,然后CURL不停的提交数据。 然后对方的网站留言或评论几十万 几十万的。然后对方的网...

eechen的粉丝
2013/06/08
474
9
centos6.5 memcached and php-memcached安装

今天要处理一堆数据,第一次从数据库取出来最少的几千,最多的几十万,不可能每次去数据库取。第一次取出成功后,由于本地windows 没有memcached环境,只好先临时保存到一个文件中,用 arra...

邻里
2016/10/13
13
0
ActiveReports 报表控件正式发布 V11 新版本

全球最大的控件提供商葡萄城宣布,ActiveReports 报表控件将于近期发布V11版本,作为产品史上的一次重大发布,新版本将包括更高效的报表引擎、更多数据源格式的支持、Excel文件导入、多Y轴组...

葡萄城控件技术团队
2016/11/25
1K
7
这是Python操作Excel表格最好的教材, 爬虫工程师都对它爱不释手

因为数据是用.csv格式保存的,所以我们通常用Excel来处理。然而其工作量是非常大的,反复操作一些相同的动作,所以Python爬虫师那种动则几十万的数据量,都会利用Python脚本来给我们处理。 ...

Python新世界
08/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

AS连接网易Mumu模拟器

1、安装模拟器 打开这个网址现在模拟器然后安装 http://mumu.163.com/ 2、安装完成后启动模拟器 3、进入模拟器安装目录 例如本机的安装目录:C:\Program Files (x86)\MuMu\emulator\nemu\vmo...

HGMrWang
20分钟前
7
0
设计要做到扩展性强还挺难的

概述 在日常开发中,有时候你的上司会跟你说,这个模块的设计扩展性要高。把这句话说出来很简单,但是要做到则非常难。导致难的其中一个因素是: 你不熟悉这个行业的业务的玩法 我举个例子来...

Sam哥哥聊技术
22分钟前
2
0
聊聊 scala 的模式匹配

一. scala 模式匹配(pattern matching) pattern matching 可以说是 scala 中十分强大的一个语言特性,当然这不是 scala 独有的,但这不妨碍它成为 scala 的语言的一大利器。 scala 的 patt...

终日而思一
24分钟前
1
0
Spring事物手动回滚

手动回滚: 方法1:在service层方法的catch语句中增加:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();语句,手动回滚,这样上层就无需去处理异常(现在项目的做法)...

寒风中的独狼
28分钟前
1
0
直角三角形的三角函数

sinA = a/c;A = asin(a/c); 特殊角度的三角函数值

一个小妞
36分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部