亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

PHP實時生成并下載超大數據量EXCEL文件的方法

發布時間:2020-11-06 14:33:03 來源:億速云 閱讀:163 作者:小新 欄目:編程語言

小編給大家分享一下PHP實時生成并下載超大數據量EXCEL文件的方法,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去探討吧!

最近接到一個需求,通過選擇的時間段導出對應的用戶訪問日志到excel中, 由于用戶量較大,經常會有導出50萬加數據的情況。

而常用的PHPexcel包需要把所有數據拿到后才能生成excel, 在面對生成超大數據量的excel文件時這顯然是會造成內存溢出的,所以考慮使用讓PHP邊寫入輸出流邊讓瀏覽器下載的形式來完成需求。

我們通過如下的方式寫入PHP輸出流

$fp = fopen('php://output', 'a');
fputs($fp, 'strings');
....
....
fclose($fp)

php://output是一個可寫的輸出流,允許程序像操作文件一樣將輸出寫入到輸出流中,PHP會把輸出流中的內容發送給web服務器并返回給發起請求的瀏覽器

另外由于excel數據是從數據庫里逐步讀出然后寫入輸出流的所以需要將PHP的執行時間設長一點(默認30秒)set_time_limit(0)不對PHP執行時間做限制。

注:

以下代碼只是闡明生成大數據量EXCEL的思路和步驟,并且在去掉項目業務代碼后程序有語法錯誤不能拿來直接運行,請根據自己的需求填充對應的業務代碼!

/**
     * 文章訪問日志
     * 下載的日志文件通常很大, 所以先設置csv相關的Header頭, 然后打開
     * PHP output流, 漸進式的往output流中寫入數據, 寫到一定量后將系統緩沖沖刷到響應中
     * 避免緩沖溢出
     */
    public function articleAccessLog($timeStart, $timeEnd)
    {
        set_time_limit(0);
        $columns = [
            '文章ID', '文章標題', ......
        ];
        $csvFileName = '用戶日志' . $timeStart .'_'. $timeEnd . '.xlsx';
        //設置好告訴瀏覽器要下載excel文件的headers
        header('Content-Description: File Transfer');
        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment; filename="'. $fileName .'"');
        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 = '1000000'//從數據庫獲取總量,假設是一百萬
        $perSize = 1000;//每次查詢的條數
        $pages   = ceil($accessNum / $perSize);
        $lastId  = 0;
        for($i = 1; $i <= $pages; $i++) {
            $accessLog = $logService->getArticleAccessLog($timeStart, $timeEnd, $lastId, $perSize);
            foreach($accessLog as $access) {
                $rowData = [
                    ......//每一行的數據
                ];
                mb_convert_variables('GBK', 'UTF-8', $rowData);
                fputcsv($fp, $rowData);
                $lastId = $access->id;
            }
            unset($accessLog);//釋放變量的內存
            //刷新輸出緩沖到瀏覽器
            ob_flush();
            flush();//必須同時使用 ob_flush() 和flush() 函數來刷新輸出緩沖。
        }
        fclose($fp);
        exit();
    }

好了, 其實很簡單,就是用逐步寫入輸出流并發送到瀏覽器讓瀏覽器去逐步下載整個文件,由于是逐步寫入的無法獲取文件的總體size所以就沒辦法通過設置header("Content-Length: $size");在下載前告訴瀏覽器這個文件有多大了。不過不影響整體的效果這里的核心問題是解決大文件的實時生成和下載。

更新: 說一下我數據庫查詢這里的思路,因為逐步寫入EXCEL的數據實際上來自Mysql的分頁查詢,大家知道其語法是LIMIT offset, num 不過隨著offset越來越大Mysql在每次分頁查詢時需要跳過的行數就越多,這會嚴重影響Mysql查詢的效率(包括MongoDB這樣的NoSQL也是不建議skip掉多條來取結果集),所以我采用LastId的方式來做分頁查詢。

類似下面的語句:

SELECT columns FROM `table_name` 
WHERE `created_at` >= 'time range start' 
AND `created_at` <= 'time range end' 
AND  `id` < LastId 
ORDER BY `id` DESC 
LIMIT num

看完了這篇文章,相信你對PHP實時生成并下載超大數據量EXCEL文件的方法有了一定的了解,想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

江华| 湟中县| 靖江市| 株洲县| 银川市| 深水埗区| 清水县| 察隅县| 乐至县| 福安市| 宿州市| 新巴尔虎左旗| 汝州市| 大名县| 信宜市| 托里县| 柳林县| 东阿县| 安义县| 耿马| 丰台区| 宣武区| 德清县| 广德县| 平和县| 东兰县| 南京市| 柯坪县| 乐至县| 方正县| 平阴县| 岳普湖县| 南丹县| 武邑县| 海口市| 新营市| 犍为县| 湘西| 霸州市| 东方市| 顺昌县|