2013-04-06 24 views
0

我想讀取一個大約20mb的excel文件導入到MySQL。phpExcel閱讀大塊如此緩慢和內存錯誤

我在互聯網上搜索,發現「大塊閱讀」的解決方案,但不工作...或對我來說是如此緩慢,我不知道爲什麼。

這是即時通訊做什麼:

// ..... 
// into MyReadFilter class.. this is the most important function: 
public function readCell($column, $row, $worksheetName = '') { 
     // Only read the rows and columns that were configured 
     if (($row == 1) || ($row >= $this->_startRow && $row < $this->_endRow)) { 
      if (in_array($column,$this->_columns)) { 
       return true; 
      } 
     } 
     return false; 
    } 
// ..... 


$filter = new MyReadFilter(1, 22000); 
$chunkSize = 10; 

$objReader = PHPExcel_IOFactory::createReader($inputFileType); 
$objReader->setReadFilter($filter); 
$objReader->setReadDataOnly(false); //not sure if this should be true 


for ($startRow = 2; $startRow <= 65536; $startRow += $chunkSize) { 

    echo "Reading"; 
    $filterSubset->setRows($startRow, $chunkSize); 
    $objPHPExcel = $objReader->load($inputFileName); // this line takes like 40 seconds... for 10 rows? 
    echo "chunk done! "; 
} 

但是,裏面的,在$ objReader->負載()正在像40秒,而事實上,經過2個循環我有一個內存錯誤。

如果我沒有設置$ objReader裏面的內容,我可以使它在內部運行大約20次(儘管需要10分鐘)和內存錯誤。

我想知道爲什麼加載函數似乎讀取所有文件,如果即時通訊使用過濾器,也過濾器策略似乎解析所有行,並返回假的所有行是不需要的...是不可能的放棄閱讀或真正閱讀所需的內容?

我試過一對夫婦FilterClass和代碼段,但得到了同樣的結果...

回答

3

如果您使用的過濾器,然後將讀卡器仍在讀取整個文件,而是隻填充PHPExcel對象細胞這是由過濾器定義的;並且Reader仍然需要讀取整個文件,每次過濾過程都是如此,從而導致速度變慢。

由於原始電子表格文件的結構,讀取器需要讀取整個文件。單元格數據不與單元格格式一起存儲,單元格內容也可以單獨存儲。讀者需要把所有這一切都放在一起。當過濾器條件滿足時,您不能簡單地中止讀取器,因爲讀者無法知道它已完成...如果您有一個過濾器將負載限制到單元格A1:C3,那麼您可以在讀完B3之後不會中止,因爲您不知道文件中的單元格B2是否在該文件之後,或者文件中可能會有與單元格A1關聯的註釋。在整個文件加載並解析之前,您無法開始過濾。

PHPExcel中的主要內存使用情況是PHPExcel對象,特別是單元(通常在32位PHP上大約爲1k /單元)....此處提供的用於減少內存的主要解決方案是單元高速緩存。這可以(使用SQLite緩存)將單元內存使用量減少到0k/cell,但速度有所降低。

閱讀器使用的內存量不如Excel文件(解壓縮)本身的大小,因此通常遠不如內存問題;但是通過從SimpleXML切換到XMLReader來解決這個問題(對於基於XML的電子表格格式)。但它取決於正在加載的文件的格式; xls格式文件與xlsx文件非常不同(xlsx會從中受益,xls不會),並且還依賴於開發人員能夠找到時間來做到這一點 - 但它是來年的路線圖,並且工作已經開始。

+0

好吧,花了數小時和數小時花在這個我決定做保存爲CSV和導入幾分鐘內完成.. – 2013-04-08 16:00:46

+0

感謝您解釋這個標記,我不確定爲什麼過濾器的結構是他們的方式我認爲「哇這是低效的,必須檢查每個細胞」。你所說的話清楚說明它爲什麼是這樣設計的。 – user984976 2015-04-25 01:10:11