濮阳杆衣贸易有限公司

主頁 > 知識庫 > PHP實現(xiàn)實時生成并下載超大數(shù)據(jù)量的EXCEL文件詳解

PHP實現(xiàn)實時生成并下載超大數(shù)據(jù)量的EXCEL文件詳解

熱門標簽:襄陽房產(chǎn)電銷機器人招商 百度地圖標注飯店位置怎么 施工地圖標注怎么做 個性化地圖標注在線 清遠陽山400電話號碼如何申請 百度地圖標注名編輯 安徽移動外呼系統(tǒng) 深圳400電話辦理那家好 怎么在高德地圖標注行走軌跡

前言

最近在工作中接到一個需求,通過選擇的時間段導出對應(yīng)的用戶訪問日志到excel中, 由于用戶量較大,經(jīng)常會有導出50萬加數(shù)據(jù)的情況。而常用的PHPexcel包需要把所有數(shù)據(jù)拿到后才能生成excel, 在面對生成超大數(shù)據(jù)量的excel文件時這顯然是會造成內(nèi)存溢出的,所以考慮使用讓PHP邊寫入輸出流邊讓瀏覽器下載的形式來完成需求。

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

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

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

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

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

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

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

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

您可能感興趣的文章:
  • PHP導出MySQL數(shù)據(jù)到Excel文件(fputcsv)
  • php+ajax實現(xiàn)帶進度條的大數(shù)據(jù)排隊導出思路以及源碼
  • phpadmin如何導入導出大數(shù)據(jù)文件及php.ini參數(shù)修改
  • phpexcel導入excel處理大數(shù)據(jù)(實例講解)
  • php 在線導入mysql大數(shù)據(jù)程序
  • 淺析THINKPHP的addAll支持的最大數(shù)據(jù)量
  • php+ajax導入大數(shù)據(jù)時產(chǎn)生的問題處理
  • php 大數(shù)據(jù)量及海量數(shù)據(jù)處理算法總結(jié)
  • php使用fputcsv實現(xiàn)大數(shù)據(jù)的導出操作詳解

標簽:臨夏 阜陽 中衛(wèi) 黑河 駐馬店 延邊 欽州 南昌

巨人網(wǎng)絡(luò)通訊聲明:本文標題《PHP實現(xiàn)實時生成并下載超大數(shù)據(jù)量的EXCEL文件詳解》,本文關(guān)鍵詞  PHP,實現(xiàn),實時,生成,并,下載,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《PHP實現(xiàn)實時生成并下載超大數(shù)據(jù)量的EXCEL文件詳解》相關(guān)的同類信息!
  • 本頁收集關(guān)于PHP實現(xiàn)實時生成并下載超大數(shù)據(jù)量的EXCEL文件詳解的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    班玛县| 贺州市| 色达县| 宾川县| 张家港市| 威宁| 自治县| 阜宁县| 三台县| 古浪县| 绍兴县| 额敏县| 航空| 凭祥市| 杂多县| 哈密市| 沈阳市| 英山县| 香港| 镇沅| 皮山县| 东海县| 赫章县| 肥东县| 康马县| 望城县| 五寨县| 巧家县| 余姚市| 嘉鱼县| 且末县| 梅河口市| 新丰县| 泗水县| 万荣县| 泗阳县| 抚顺市| 黑山县| 讷河市| 平顶山市| 吴堡县|