最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時(shí)間:2017年10月23日 09:21:19   作者:KevinYan  
EXCEL文件的處理是我們?cè)谌粘9ぷ髦薪?jīng)常會(huì)遇到的,這篇文章主要給大家介紹了關(guān)于利用PHP如何實(shí)現(xiàn)實(shí)時(shí)生成并下載超大數(shù)據(jù)量的EXCEL文件,通過(guò)文中介紹的這個(gè)方法對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。

前言

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

我們通過(guò)如下的方式寫(xiě)入PHP輸出流

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

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

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

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

 /**
  * 文章訪問(wèn)日志
  * 下載的日志文件通常很大, 所以先設(shè)置csv相關(guān)的Header頭, 然后打開(kāi)
  * PHP output流, 漸進(jìn)式的往output流中寫(xiě)入數(shù)據(jù), 寫(xiě)到一定量后將系統(tǒng)緩沖沖刷到響應(yīng)中
  * 避免緩沖溢出
  */
 public function articleAccessLog($timeStart, $timeEnd)
 {
  set_time_limit(0);
  $columns = [
   '文章ID', '文章標(biāo)題', ......
  ];
  $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');//打開(kāi)output流
  mb_convert_variables('GBK', 'UTF-8', $columns);
  fputcsv($fp, $columns);//將數(shù)據(jù)格式化為CSV格式并寫(xiě)入到output流中
  $accessNum = '1000000'//從數(shù)據(jù)庫(kù)獲取總量,假設(shè)是一百萬(wàn)
  $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();//必須同時(shí)使用 ob_flush() 和flush() 函數(shù)來(lái)刷新輸出緩沖。
  }
  fclose($fp);
  exit();
 }

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

總結(jié)

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

  • 用mysql_fetch_array()獲取當(dāng)前行數(shù)據(jù)的方法詳解

    用mysql_fetch_array()獲取當(dāng)前行數(shù)據(jù)的方法詳解

    本篇文章是對(duì)使用mysql_fetch_array()獲取當(dāng)前行數(shù)據(jù)的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • php類自動(dòng)加載器實(shí)現(xiàn)方法

    php類自動(dòng)加載器實(shí)現(xiàn)方法

    這篇文章主要介紹了php類自動(dòng)加載器實(shí)現(xiàn)方法,涉及php針對(duì)文件的讀取、判斷及字符串操作的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • PHP實(shí)現(xiàn)獲取客戶端IP并獲取IP信息

    PHP實(shí)現(xiàn)獲取客戶端IP并獲取IP信息

    這篇文章主要介紹了PHP實(shí)現(xiàn)獲取客戶端IP并獲取IP信息的方法示例,非常實(shí)用,有需要的小伙伴快來(lái)參考下吧。
    2015-03-03
  • ThinkPHP like模糊查詢,like多匹配查詢,between查詢,in查詢,一般查詢書(shū)寫(xiě)方法

    ThinkPHP like模糊查詢,like多匹配查詢,between查詢,in查詢,一般查詢書(shū)寫(xiě)方法

    ThinkPHP的數(shù)據(jù)庫(kù)條件查詢語(yǔ)句有字符串式,數(shù)組式書(shū)寫(xiě)方法,字符串式即是原生式而數(shù)組式的查詢語(yǔ)句因書(shū)寫(xiě)方式與特定字符的原因比較復(fù)雜,今天為大家講解一下ThinkPHP數(shù)組式查詢語(yǔ)句的書(shū)寫(xiě)方法
    2018-09-09
  • php常量詳細(xì)解析

    php常量詳細(xì)解析

    這篇文章主要介紹了php常量,常量的語(yǔ)法分析,區(qū)分常量和變量的不同之處,以及什么是預(yù)定義常量,對(duì)這方面感興趣的朋友可以借鑒借鑒。
    2015-10-10
  • 簡(jiǎn)單談?wù)?php 文件鎖

    簡(jiǎn)單談?wù)?php 文件鎖

    PHP出現(xiàn)文件鎖與mysql表鎖有大概想的用法,就是同一時(shí)間只能讓一個(gè)人操作,這樣就避免了同時(shí)有多個(gè)人操作同一文件,這樣導(dǎo)致數(shù)據(jù)丟失的情況了,下面我來(lái)給大家介紹PHP文件鎖用法。
    2017-02-02
  • Linux環(huán)境下搭建php開(kāi)發(fā)環(huán)境的操作步驟

    Linux環(huán)境下搭建php開(kāi)發(fā)環(huán)境的操作步驟

    本篇文章是對(duì)Linux環(huán)境下搭建php開(kāi)發(fā)環(huán)境的操作步驟進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • PHP無(wú)限極分類函數(shù)的實(shí)現(xiàn)方法詳解

    PHP無(wú)限極分類函數(shù)的實(shí)現(xiàn)方法詳解

    這篇文章主要介紹了PHP無(wú)限極分類函數(shù)的實(shí)現(xiàn)方法,結(jié)合實(shí)例形式詳細(xì)分析了php實(shí)現(xiàn)無(wú)限極分類的具體思路、實(shí)現(xiàn)代碼與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2017-04-04
  • 最新評(píng)論

    诏安县| 高尔夫| 平乐县| 微山县| 漯河市| 和平区| 应城市| 大城县| 石渠县| 永丰县| 鹤山市| 黄浦区| 抚顺县| 永春县| 平阴县| 沙坪坝区| 墨脱县| 大庆市| 循化| 济南市| 西宁市| 开阳县| 武宣县| 招远市| 惠安县| 湖北省| 寻甸| 资阳市| 深圳市| 南安市| 南康市| 岑溪市| 镇雄县| 香河县| 新野县| 乌鲁木齐县| 罗定市| 佛山市| 石台县| 宁强县| 柏乡县|