PHPExcel大文件塊級別讀取 速度快 減少佔用資源

  /**
     * 讀取excel轉換成數組
     *
     * @param string $excelFile 文件路徑
     * @param int $startRow 開始讀取的行數
     * @param int $endRow 結束讀取的行數
     * @return array
     */
    private function readFromExcel($excelFile, $startRow = 1, $endRow = 100) {
        include_once './Core/Common/PHPExcel.php';
        include_once './Core/Common/PHPExcelReadFilter.php';

        $excelType = PHPExcel_IOFactory::identify($excelFile);
        $excelReader = \PHPExcel_IOFactory::createReader($excelType);

        if(strtoupper($excelType) == 'CSV') {
            $excelReader->setInputEncoding('GBK');
        }

        if ($startRow && $endRow) {
            $excelFilter           = new PHPExcelReadFilter();
            $excelFilter->startRow = $startRow;
            $excelFilter->endRow   = $endRow;
            $excelReader->setReadFilter($excelFilter);
        }

        $phpexcel    = $excelReader->load($excelFile);
        $activeSheet = $phpexcel->getActiveSheet();

        $highestColumn      = $activeSheet->getHighestColumn(); //最後列數所對應的字母,例如第1行就是A
        $highestColumnIndex = \PHPExcel_Cell::columnIndexFromString($highestColumn); //總列數

        $data = array();
        for ($row = $startRow; $row <= $endRow; $row++) {
            for ($col = 0; $col < $highestColumnIndex; $col++) {
                $data[$row][] = (string) $activeSheet->getCellByColumnAndRow($col, $row)->getValue();
            }
            if(implode($data[$row], '') == '') {
                unset($data[$row]);
            }
        }
        return $data;
    }
$rowSize = 200; 
$startRow = 2;//從第二行開始讀取
$endRow = $rowSize;
$excel_orders = array();
while (true) {
  $excel_orders = $this->readFromExcel(dirname(dirname(HOME_PATH)).'/Upload/'.$newname, $startRow, $endRow);
    if(empty($excel_orders)) {
          break;
    }
    $startRow = $endRow + 1;
    $endRow = $endRow + $rowSize;
}
/**
 * 讀取excel過濾器類 單獨文件
 */
class PHPExcelReadFilter implements PHPExcel_Reader_IReadFilter {

    public $startRow = 1;
    public $endRow;

    public function readCell($column, $row, $worksheetName = '') {
        if (!$this->endRow) {
            return true;
        }
        
        if ($row >= $this->startRow && $row <= $this->endRow) {
            return true;
        }

        return false;
    }

}

 

描述:用戶導入訂單數據,但用戶導入8k左右的數據之後,PHP開始爆紅了。

查閱部分資料得知,是由於PHPExcel的類讀取,如果使用

$PHPExcel = $PHPReader->load($newfilename);

load的方式讀取文件的話,是把文件中的全部內容讀出並儲存在內存中,再讀取內容的話,就是直接從內存中讀取,極其消耗資源。

而以上代碼片段實現的效果就是我需要那塊(n-m行)的內容,我只讀去那部分的內容,不會加載整個文件。

最後,使用完變量,可以進行 $a = null; / unset($a); 進行釋放資源。

祝工作順利!

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