PHPExcel刪除sheet數據

一、用PHPExcel導出表格。

先看導出類代碼,網上也有很多類似代碼。

構造方法:

public function __construct(){
        class_exists('PHPExcel') || require_once EXTEND_PATH."PHPExcel/Classes/PHPExcel.php";
        // 設置導出緩存
        $cacheMethod = \PHPExcel_CachedObjectStorageFactory::cache_to_phpTemp;
        $cacheSettings = array('memoryCacheSize' => '16MB');
        \PHPExcel_Settings::setCacheStorageMethod($cacheMethod,$cacheSettings);
        $excelObj = new \PHPExcel();
        $this->excelObj = $excelObj;
}

導出執行方法:

public function execute(){
        $this->check();
        //重複調用execute時,刪除之前sheet和數據
        $activeSheet = $this->excelObj->setActiveSheetIndex(0);
        $rowNum = $activeSheet->getHighestDataRow();
        if($rowNum > 1){
            //取消表格和excel的關聯
            $this->excelObj->disconnectWorksheets();
            $this->excelObj->createSheet(0);
            $activeSheet = $this->excelObj->setActiveSheetIndex(0);
        }
        // 寫入表頭
        // 寫入數據
}

我們導出的表格比較簡單,只有一個sheet,所以簡單粗暴地設置了index=0。一個場景:我要導出大量的訂單數據,放在一個表格,會有內存溢出的問題,所以設置爲每1000單放在一個表格。每次都設置導出的訂單數據,這裏有一個問題,其實循環操作的是同一個activeSheet,比如上次設置的sheet數據有1000行,而最後一次訂單數據不滿1000行只有500行,這時最後一個表格數據還是有1000行,只是後面的500行數據是之前表格的。

這是我選擇的處理方式:

1.移除原有sheet,新建一個sheet,這樣還是會報內存溢出的錯誤,不清楚是怎麼處理sheet移除的,對象應該還沒銷燬。

$this->excelObj->removeSheetByIndex(0);
$this->excelObj->createSheet(0);
$activeSheet = $this->excelObj->setActiveSheetIndex(0);

2.每次檢查activeSheet有數據的最大行數(空的sheet默認還是有1行),行數大於1的時候,刪除所有行。

$activeSheet->remove(1,$rowNum);

以爲這樣就解決了,後來發現這個remove方法根本沒有任何效果。

3.嘗試取消所有單元格和activeSheet的關聯,向下面這樣,結果報錯了。

$activeSheet->disconnectCells();

4.嘗試取消activeSheet和excel對象的關聯,新建一個sheet。這次可以正常導出多個表格,而且數據是正確的。

$this->excelObj->disconnectWorksheets();
$this->excelObj->createSheet(0);
$activeSheet = $this->excelObj->setActiveSheetIndex(0);

二、下載文件的過程

要導出訂單數據,之前一直是生成excel表格和下載在一起處理的。這樣在訂單數量少的時候沒什麼問題,幾乎點下下載,文件也就跟着下載了。但是數據多的時候,要等很久,用戶有可能還會不停點幾下。後來改成點擊按鈕,異步請求服務器生成訂單文件,生成完成後,告訴瀏覽器文件的路徑,然後再由瀏覽器請求文件。

這樣做有幾個好處:

1.給用戶提示。生成文件和下載放一起的話,服務器是沒辦法和用戶有什麼交互,因爲常見的下載方式,就是將a標籤的href設置爲後臺的一個處理方法,或者用js寫個方法設置windows.location.href=url這樣,下載就完全交給瀏覽器處理了。前端無法知道什麼時候開始下載,這就無法在用戶點擊鏈接或按鈕到開始下載文件之前,給用戶提示,因爲我們的文件是需要實時生成的,需要時間,這段時間要防止用戶重複點擊,更重要的是給用戶提示,您想要的操作已經在執行了,耐心等待就好了。

2.分擔服務器壓力。生成文件和下載分離,其實下載文件處理的內容比較少。

3.功能更清晰。生成文件和下載分開處理,這中間有可以和瀏覽器交互的節點,生成文件開始,生成文件成功或失敗;後臺也可以有在生成文件和下載文件的代碼中增加其他處理邏輯。

三、生成的臨時文件保存在服務器

生成的文件會保存在服務器,需要每個客戶點擊時,生成不同的文件名,我用了一個生成簡單隨機字符串的方法,這個有很多。另外,可以用計劃任務定期清理臨時文件。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章