登录

php怎么导出大量数据的Excel

比较常用的是用PHPExcel,1万左右数据还行,但是数据到达100万左右,PHPExcel就显的很无助,搜索了下比较常用的是使用php的fputcsv,不知道还有什么办法能导出比较大量数据的excle


刚刚测试了下fputcsv,发现全部挤到A中,无法换到B中

2012年9月2日添加
03版的确实是有限制的,格式php的csv的是不是用excel打开只会出现在A列上面?

2012年9月2日添加
我觉得我非常有必要说下为什么会有这个需求,一个大点的品牌公司,一年左右的订单,超过100万是很正常的,年末的时候他们的业务人员会根据订单进行各种分析,每个公司的分析角度又是不一样的,所以把所有订单导出来给业务人员是一个最简单的办法,为什么要导出excle,是因为对于业务人员来说这个是最常用的,你也不可能去帮助那么多家的公司开发这样那样的报表。
所以也就有了这个需求,怎么导出超过100万甚至1000万数据excle的问题

# PHP
阿神阿神2153 天前746 次浏览

全部回复(10) 我要回复

  • PHP中文网

    PHP中文网2017-04-10 13:13:40

    1. PHP从数据库分多次读取100万行记录,和分多次将100万行写入文本文件都没问题
    2. Excel可以支持100万行记录,Excel 2003最大支持65536行,从2007版开始支持104万行了,目前2007的盗版应该比较普及了-_-! 问清楚你的客户是什么版本。
    3. 你要导出excel的理由是非常充分和正确的,应该继续坚持。业务人员最熟悉的就是Excel,实在不熟悉现学现用也比别的快。只是要注意,当数据量达到10万行这个级别时,Excel的公式填充将会非常非常慢,如果再有LOOKUP()公式,基本上十分钟内处理CPU满载进程管理器杀不掉的状态,这时候其实xampp + phpmyadmin是一个易用性和性能都最平衡的选择
    4. PHPExcel输出的是Excel XML格式,有个XML头和尾,中间是数据Body,需要将100万行都赋值给一个数组才可以调用PHPExcel->write(),这容易导致PHP执行超时或者内存超限,你不妨调整一下php.ini配置,把超时时间和内存限制都改到很大
    5. 如果是输出csv格式,那就太简单了,你的问题可能是没给字段内容加引号,加上引号再调用fputcsv试试?其实fputcsv做的事情特别简单,你甚至可以不管它,自己把CSV文件的每一行拼接好了之后用file_put_contents写入

    最后给你看一个phpmyadmin导出的CSV示例,对照你自己生成的CSV示例,看看哪里不一样。

    回复
    0
  • 阿神

    阿神2017-04-10 13:13:40

    之前我导出都是用csv的,如果putcsv有问题,你可以尝试自己去拼装csv的文件。csv的格式非常简单,就是英文逗号分隔。
    看你截图,有可能是首行留空造成的问题,建议修改试试。
    ---
    还有一个办法,就是用 \t 分割,存成文本文件,然后复制黏贴到excel里

    回复
    0
  • PHP中文网

    PHP中文网2017-04-10 13:13:40

    很赞同2楼的说法。
    excel本身就不是为大数据而操作的,如果你真的过10万行,你还是不要用excel来操作了,这样真的会死人的。
    当然如果你真的要操作,你还是存到access中。然后用excel来读取access的数据来生成各种图表(如果你的excel是为了要用来生成图表的话)。
    否则,真没意义啊。

    回复
    0
  • ringa_lee

    ringa_lee2017-04-10 13:13:40

    如果我没记错的话,Excel极限是65536条。

    回复
    0
  • ringa_lee

    ringa_lee2017-04-10 13:13:40

    1.Excel本身就不能装几百万数据。Excel是有条数限制的。具体多少条你可以查阅相关资料。
    2.你可以将数据按照条数进行分割写入不同的Excel文件。生成多个。
    3.即使你写入csv文件,你想用Excel打开几百万数据也不太现实

    回复
    0
  • PHP中文网

    PHP中文网2017-04-10 13:13:40

    excel分列就好了

    回复
    0
  • 迷茫

    迷茫2017-04-10 13:13:40

    可以csv , 不段的刷新缓冲期,来实现大数据流的导出

    $fp = fopen('php://output', 'a');
    
    // 输出Excel列名信息
    $head = array("电子邮件");
    foreach ($head as $i => $v) {
        // CSV的Excel支持GBK编码,一定要转换,否则乱码
        $head[$i] = iconv('utf-8', 'gbk', $v);
    }
    
    // 将数据通过fputcsv写到文件句柄
    fputcsv($fp, $head);
    
    // 计数器
    $cnt = 0;
    // 每隔$limit行,刷新一下输出buffer,不要太大,也不要太小
    $limit = 100000;
    
    // 逐行取出数据,不浪费内存
    $count = count($email);
    
    for($t=0;$t<$count;$t++) {
    
        $cnt ++;
        if ($limit == $cnt) { //刷新一下输出buffer,防止由于数据过多造成问题
            ob_flush();
            flush();
            $cnt = 0;
        }
        $row[] = $email[$t];
        foreach ($row as $i => $v) {
            $row[$i] = iconv('utf-8', 'gbk', $v);
        }
        fputcsv($fp, $row);
        unset($row);
    }

    循环生成CSV 数据, 每生成1000 条的时候刷新下缓冲期

    回复
    0
  • PHP中文网

    PHP中文网2017-04-10 13:13:40

    $filename='./file.csv';
    $handle=fopen($filename,"w");
    fwrite($handle,chr(255).chr(254));
    fwrite($handle,iconv("UTF-8","UTF-16LE","值1\t值2\t值3\t值n\\r\n"));
    fclose($handle);

    用这个看下,别一下查询出全部数据,你可以参考下mysql_unbuffered_query

    回复
    0
  • 阿神

    阿神2017-04-10 13:13:40

    03版的确实是有限制的,格式php的csv的是不是用excel打开只会出现在A列上面?

    回复
    0
  • 阿神

    阿神2017-04-10 13:13:40

    我正有这个需求

    回复
    0
  • 取消回复发送