2013-04-06 25 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