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 />\n";
  //flush(); //刷新緩存(直接發送到瀏覽器)
  sleep(1);
}
echo '輸出完畢';

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM