【问题标题】:phpExcel Read in chunks so slow and memory errorsphpExcel 分块读取太慢和内存错误
【发布时间】:2013-04-06 14:00:18
【问题描述】:

我正在尝试读取大约 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! ";
}

但是,在 for 内部,$objReader->load() 大约需要 40 秒,事实上,在 2 次循环之后,我遇到了内存错误。

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

我想知道如果我使用过滤器,为什么加载函数似乎读取了所有文件,过滤器策略似乎解析所有行并为所有不需要的行返回 false...不可能中止阅读还是真的只阅读所需的内容?

我尝试了几个 FilterClass 和代码 sn-ps 但得到了相同的结果...

【问题讨论】:

    标签: phpexcel


    【解决方案1】:

    如果您正在使用过滤器,那么阅读器仍在读取整个文件,但只会填充过滤器定义的 PHPExcel 对象单元格;并且 Reader 仍然需要在每次过滤过程中读取整个文件,这就是它变慢的原因。

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

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

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

    【讨论】:

    • 好的,经过数小时的努力,我决定保存为 CSV,导入在几分钟内就完成了..
    • 感谢您解释这个标记,我不确定为什么过滤器的结构与我认为的那样“哇,这效率低下,必须检查每个单元格”。您所说的清楚地说明了为什么要这样设计。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-17
    • 2016-08-05
    • 1970-01-01
    • 2020-01-26
    • 1970-01-01
    相关资源
    最近更新 更多