使用 PHPSpreadsheet 构建非常大的电子表格

2022-08-30 20:37:02

我正在测试PHPSpreadsheet如何与大型Excel电子表格一起工作。初步测试表明,对于大型电子表格,内存将很快耗尽。

有没有办法逐步编写电子表格?

我有一段旧代码,我已经用了很长时间从PHP创建电子表格。它使用非常古老的标准,并且应该进行更新。但是我的旧代码的一个优点是,我可以随它一直写入文件,而不是在内存中构建整个东西,因此可以轻松处理非常大的电子表格而不会破坏内存限制。

在PHPSpreadsheet中可以做类似的事情吗?我尝试过阅读文档,并搜索了各种论坛,但大多数回复似乎只是“增加可用内存”。


答案 1

不幸的是,PHPExcel和PHPSpreadsheet对于大文件的性能不是很高。

您的选择非常有限:

  • 不断增加内存限制
  • 将数据分块到单独的电子表格中
  • 回退到 CSV(使用 PHP 的内置函数)

Maarten的缓存建议是一个好主意,但根据我的经验,它带来了巨大的速度成本,完全抵消了任何内存优势。


我的建议是完全放弃PHPSpreadsheet,尝试box/spout。

它的构建考虑了性能,并承诺无论文件大小如何,都使用不到3MB的内存!它不仅具有内存效率,而且比PHPSpreadsheet快20-30倍。

它有一些限制(仅支持3种文件格式,没有自动列宽,没有列号/字符串格式),但我认为其中一些缺少的功能是计划中的,目前它是我处理编写大量电子表格的最佳选择。

注意:在版本 3 性能问题得到解决之前,您可能希望坚持使用版本 2.7

我没有尝试过的另一个选项是PHP_XLSXWriter。似乎有与喷嘴相似的目标


答案 2

在他们的文档中有一个关于此的主题:

https://phpspreadsheet.readthedocs.io/en/latest/topics/memory_saving/#memory-saving

您基本上可以将单元格存储在缓存中,例如在Redis中(来自其文档):

$client = new \Redis();
$client->connect('127.0.0.1', 6379);
$pool = new \Cache\Adapter\Redis\RedisCachePool($client);
$simpleCache = new \Cache\Bridge\SimpleCache\SimpleCacheBridge($pool);

\PhpOffice\PhpSpreadsheet\Settings::setCache($simpleCache);

如果您使用 Predis,则可以使用以下存储库:

https://github.com/php-cache/predis-adapter

并使用以下代码:

$client = new \Predis\Client($yourParameters, $yourOptions);
$pool = new \Cache\Adapter\Predis\PredisCachePool($client);
$simpleCache = new \Cache\Bridge\SimpleCache\SimpleCacheBridge($pool);

\PhpOffice\PhpSpreadsheet\Settings::setCache($simpleCache);

推荐