【问题标题】:PHPExcel load function running out of memoryPHPExcel加载函数内存不足
【发布时间】:2013-10-22 12:22:35
【问题描述】:

当我使用这个功能时:

$objPHPExcel = PHPExcel_IOFactory::load($fileName);

在较小的 excel 文件上,这需要一段时间,但最终会在 $objPHPExcel 中得到一个广泛的数组...不幸的是,当我在一个稍大更复杂的 Ecel 文件上尝试它时,我得到:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 32 bytes)

该文件是一个 xlsm 文件,大小为 1.7MB...这听起来是正确的还是发生了什么可疑的事情?

我认为这就是您需要的所有代码。我正在用完目前在本地设置的默认 WAMP。

【问题讨论】:

  • 那么您尝试使用哪些用于减少 PHPExcel 内存使用的单元缓存选项?我们提供并精确记录此功能,以允许处理比内存通常允许的更大的电子表格文件
  • 我专门挑选了一张要使用的工作表,并将文件从 xlsm 转换为 xlsx……这至少让我现在可以使用该工具。耶!例如: setLoadSheetsOnly( $sheetname );
  • @MarkBaker - 很荣幸能与制作这些东西的人“交谈”:)
  • 我需要逐行读取 Excel 文件。当文件大小大于 11MB 时,它会一直耗尽内存。 PHPExcel_CachedObjectStorageFactory::cache_to_discISAMPHPExcel_CachedObjectStorageFactory::cache_to_phpTemp 都无法解决问题。我的 PHP 内存限制是 134217728 字节。

标签: php memory phpexcel


【解决方案1】:

我有同样的问题。在我们公司,我们需要将巨大的 xls(x) 文件导入我们的数据库。我们一直在使用 PEAR 电子表格 Excel 阅读器,但它不再受支持,而且我们遇到了许多更新文件的错误,因此我们尝试切换到 PHPExcel。 不幸的是,我们没有设法克服内存限制问题。我们花了很多时间来尝试。 您无法使用 PHPExcel 加载 100K 行,其中的列最多为 'BB'。

它只是不适合这项工作的工具。 PHP Excel 在内存中构建整个电子表格作为对象。没有办法解决这个问题。

您需要的是一个可以逐行、逐个单元格地读取文件的工具。

我们的解决方案是使用带有事件模型的 Java 和 Apache POI 类 - 它执行只读操作,但内存和 CPU 效率非常高。

如果您只需要支持基于 xml 的“Office Open XML”格式 (xlsx) 而不是基于旧的 OLE,那么您可以将其作为自己的 XML 进行处理。如果你进入它,格式并没有那么复杂。只需解压缩文件并查看 xml。您有一个包含字符串表的文件,以及一个包含每个工作表的行和单元格的文件。 您应该先解析字符串表,然后使用 xml 阅读器(而不是 DOM)解析工作表数据。

据我所知,截至 2013 年 10 月,还没有可以直接导入大型 excel 文件的 PHP 库。

祝你好运。

【讨论】:

  • PHPExcel 记录了减少内存使用的功能,例如单元格缓存;并且 SQLite 缓存选项特别有效....您尝试过使用它吗?
  • 注意Excel文件的结构(OfficeOpenXML无论是BIFF还是BIFF都不利于逐行/逐单元读取文件
  • BIFF 格式是对的,它首先定义了所有行,然后是单元格数据。但是,当您使用基于事件的阅读器(如 Apache POI)时,当阅读器读取一个行对象或一个单元格对象时,您会收到一个事件。而且你不必全部加载到内存中
  • 抱歉,按回车键,然后错过了 5 分钟的编辑时间。
  • 不导电是什么意思?当您使用基于事件的阅读器(如 Apache POI)时,当阅读器读取一个行对象或一个单元格对象时,您会收到一个事件。因此,您可以只对单元格记录做出反应,它们按顺序存储(或至少 POI 按顺序读取它们),因此当您获得下一行的第一个单元格时,您可以将最后一个完整行存储在 db 中并继续到下一个。对于 XML 格式,它们可以被基于事件的阅读器读取,而无需构建 dom,并且每个单元格都是每一行的子级。唯一的问题是共享字符串表,它可能很大,必须先加载。
【解决方案2】:

根据我的经验,PHPExcel 在很多操作过程中都会耗尽内存。

您可以尝试提高脚本的内存限制。

ini_set('memory_limit','256M');

【讨论】:

  • 致命错误:超过 30 秒的最大执行时间...我如何延长执行时间 ^_^...虽然快速修复会让我开心..我不确定我在实时服务器上会有多少选择......但也许我可以将我的网站移动到我有更多选择的地方呵呵
  • @JamesT : ini_set('max_execution_time', 0);...也许你应该考虑一种对资源更友好的输入格式,通常好的旧 csv 就足够了;)
  • @JamesT 是的,过多增加内存限制可能不是一个明智的选择,显然这不是一个很好的解决方案,但我发现的唯一另一件事是使用如果可以的话,PHPExcel。例如,我有一组数据库行,我试图输出到 Excel 文件,我必须创建一个 ajax 脚本,该脚本将循环并分块执行,以阻止它耗尽内存。
  • 是的,耻辱..我不确定这是一种选择...可能不得不让客户失望,呵呵。 “伙计们,请把那个废话导出到 csv”......我会用这些话说出来
  • xlsm文件的内容是什么样的?
猜你喜欢
  • 2012-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-28
  • 2014-09-15
  • 2011-02-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多