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 '输出完毕';
  • 相关阅读:
    There is an overlap in the region chain修复
    There is an overlap in the region chain
    region xx not deployed on any region server
    python 中的re模块,正则表达式
    TCP粘包问题解析与解决
    yield from
    Git push提交时报错Permission denied(publickey)...Please make sure you have the correct access rights and the repository exists.
    mysql 中Varchar 与char的区别
    Mysql 字符集及排序规则
    请实现一个装饰器,限制该函数被调用的频率,如10秒一次
  • 原文地址:https://www.cnblogs.com/xuey/p/9567067.html
Copyright © 2011-2022 走看看