phpExcel读块速度太慢,内存错误

phpExcel读块速度太慢,内存错误,phpexcel,Phpexcel,我正在尝试读取一个大约20mb的大型excel文件,以便导入mysql 我在互联网上搜索并找到了“块阅读”解决方案,但是它不起作用。。。或者对我来说太慢了,我不知道为什么 这就是我所做的: // ..... // into MyReadFilter class.. this is the most important function: public function readCell($column, $row, $worksheetName = '') { // Only

我正在尝试读取一个大约20mb的大型excel文件,以便导入mysql

我在互联网上搜索并找到了“块阅读”解决方案,但是它不起作用。。。或者对我来说太慢了,我不知道为什么

这就是我所做的:

// .....
// 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! ";
}
/。。。。。
//进入MyReadFilter类。。这是最重要的功能:
公共函数readCell($column,$row,$worksheetName=''){
//仅读取已配置的行和列
如果(($row==1)| |($row>=$this->_startRow&&$row<$this->_endRow)){
if(在_数组($column,$this->_columns)中){
返回true;
}
}
返回false;
}
// .....
$filter=newmyreadfilter(12200);
$chunkSize=10;
$objReader=PHPExcel\u IOFactory::createReader($inputFileType);
$objReader->setReadFilter($filter);
$objReader->setReadDataOnly(false)//不确定这是否是真的
对于($startRow=2;$startRow setRows($startRow,$chunkSize);
$objPHPExcel=$objReader->load($inputFileName);//这行大约需要40秒……10行?
回显“块完成!”;
}
然而,在for中,$objReader->load()大约需要40秒,事实上,在两次循环之后,我得到了一个内存错误

如果我在for中取消设置$objReader,我可以使它在for…(虽然需要10分钟)和..内存错误中运行大约20次

我想知道,如果我使用过滤器,为什么加载函数似乎会读取所有文件,而且过滤器策略似乎会解析所有行,并为所有不需要的行返回false…无法中止读取或仅读取所需的行


我尝试了几个FilterClass和代码片段,但得到了相同的结果…

如果使用过滤器,则读取器仍在读取整个文件,但仅填充过滤器定义的PHPExcel对象单元格;并且读取器在每次过滤过程中仍需读取整个文件,这就是它的原因奥威尔

由于原始电子表格文件的结构,读卡器需要读取整个文件。单元格数据不是以单元格格式存储的,单元格内容也可能单独存储。读卡器需要将所有这些内容放在一起。当满足筛选条件时,不能简单地中止读卡器,因为读卡器无法知道这一点它已经完成…如果您有一个限制加载到单元格A1:C3的筛选器,那么在读取B3后您无法中止,因为您不知道文件中单元格B2是否在该单元格之后,或者文件中可能还有与单元格A1相关联的注释。在加载和解析整个文件之前,您无法开始筛选

PHPExcel中的主内存使用是PHPExcel对象,特别是单元(通常在32位PHP上约为1k/单元)……这里提供的减少内存的主要解决方案是单元缓存。这可以(使用SQLite缓存)将单元内存使用量减少到0k/单元,尽管速度上有一定的代价


读卡器使用的内存并不比Excel文件(解压缩)本身的大小多,因此通常内存问题要小得多;但这一点正在得到解决(对于基于XML的电子表格格式)通过从SimpleXML切换到XMLReader。但这取决于加载的文件的格式;xls格式的文件与xlsx文件非常不同(xlsx将从中受益,xls不会)而且还取决于开发人员是否能够找到时间来做这件事——但这已经在来年的路线图上,而且工作已经开始了。

如果您使用的是过滤器,那么读卡器仍在读取整个文件,但只填充过滤器定义的PHPExcel对象单元格;读卡器仍需要读取他在过滤过程中的每一个过程中都会用到整个文件,这使得过滤速度变慢

由于原始电子表格文件的结构,读卡器需要读取整个文件。单元格数据不是以单元格格式存储的,单元格内容也可能单独存储。读卡器需要将所有这些内容放在一起。当满足筛选条件时,不能简单地中止读卡器,因为读卡器无法知道这一点它已经完成…如果您有一个限制加载到单元格A1:C3的筛选器,那么在读取B3后您无法中止,因为您不知道文件中单元格B2是否在该单元格之后,或者文件中可能还有与单元格A1相关联的注释。在加载和解析整个文件之前,您无法开始筛选

PHPExcel中的主内存使用是PHPExcel对象,特别是单元(通常在32位PHP上约为1k/单元)……这里提供的减少内存的主要解决方案是单元缓存。这可以(使用SQLite缓存)将单元内存使用量减少到0k/单元,尽管速度上有一定的代价


读卡器使用的内存并不比Excel文件(解压缩)本身的大小多,因此通常内存问题要小得多;但这一点正在得到解决(对于基于XML的电子表格格式)通过从SimpleXML切换到XMLReader。但这取决于加载的文件的格式;xls格式的文件与xlsx文件非常不同(xlsx将从中受益,xls不会)这也取决于开发人员能否找到时间来做这件事——但这已经在来年的路线图上了,工作已经开始了。

好的,在花了好几个小时之后,我决定做“另存为CSV”,并在几分钟内完成导入。感谢您解释这个标记,我不确定为什么要构造过滤器他们的方式就像我所想的“哇,这是低效的,必须检查每个单元格”。你所说的清楚地说明了为什么它是这样设计的。好的,在花了好几个小时之后,我决定保存为CSV,导入在几分钟内完成。感谢你解释这个标记,我不确定为什么过滤器是结构化的