zoukankan      html  css  js  c++  java
  • PHP 实时生成并下载超大数据量的 Excel 文件

       //另外由于excel数据是从数据库里逐步读出然后写入输出流的所以需要将PHP的执行时间设长一点
        //(默认30秒)set_time_limit(0)不对PHP执行时间做限制。
        set_time_limit(0);
        $columns = [
           '文章ID', '文章标题', ...... //'openid'
        ];
        //处理需要导出的数据
        $timeStart = strtotime('2018-08-08 00:00:00');
        $timeEnd = strtotime('2018-08-08 23:59:59');
        $arr = DB::table('t_wechat_user_wx4ed9e1f4e0f3eeb0')->select(DB::raw('distinct openid'))->where('subscribe_time','>=',$timeStart)->where('subscribe_time','<=',$timeEnd);
    
        $csvFileName = '8月8号新增粉丝openid.xlsx';
        //设置好告诉浏览器要下载excel文件的headers
        header('Content-Description: File Transfer');
        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment; filename="'. $csvFileName .'"');
        header('Expires: 0');
        header('Cache-Control: must-revalidate');
        header('Pragma: public');
        $fp = fopen('php://output', 'a');//打开output流
        mb_convert_variables('GBK', 'UTF-8', $columns);
        fputcsv($fp, $columns);//将数据格式化为CSV格式并写入到output流中
        $accessNum = $arr->count();//从数据库获取总量,假设是一百万
        $perSize = 1000;//每次查询的条数
        $pages   = ceil($accessNum / $perSize);
        $lastId  = 0;
        for($i = 1; $i <= $pages; $i++) {
            //需要导出的数据
            $accessLog = $arr->offset($lastId)->limit($perSize)->get(['openid'])->toArray();
            foreach($accessLog as $access) {
                $rowData = [
                    ......//每一行的数据  $access->openid
                ];
                mb_convert_variables('GBK', 'UTF-8', $rowData);
                fputcsv($fp, $rowData);
                $lastId ++;
            }
            unset($accessLog);//释放变量的内存
            //刷新输出缓冲到浏览器
            ob_flush();
            flush();//必须同时使用 ob_flush() 和flush() 函数来刷新输出缓冲。
        }
        fclose($fp);
        exit();

    相关实时输出:

    1. 通过设置实现实时输出

    ob_end_flush();//关闭缓存
    ob_implicit_flush(true);// TRUE 打开绝对刷送 每次缓存即时输出 相当于每次输出后调用flush()
    header('X-Accel-Buffering: no'); //关闭输出缓存

    2. 通过 php 语法实现实时输出 

    $buffer = ini_get('output_buffering');
    echo str_repeat(' ',$buffer+1); //防止浏览器缓存
    ob_end_flush(); //关闭缓存
    for( $i=1; $i<=10; $i++ ){
      echo ''.$i.' 次输出.'."<br />
    ";
      //flush(); //刷新缓存(直接发送到浏览器)
      sleep(1);
    }
    echo '输出完毕';
  • 相关阅读:
    Document
    JavaScript
    day6 双向循环及pass、break、continue的使用以及for循环
    day5 isinstance&代码块&分支&while循环
    day4:运算符
    day3:强制类型转换&自动类型转换&变量缓存机制
    day2:Number,tuple,str,list,set,dict
    day1:注释和变量
    线段树区间修改+查询区间和
    Prim/Kruskal求最小生成树
  • 原文地址:https://www.cnblogs.com/xuey/p/9567067.html
Copyright © 2011-2022 走看看