【问题标题】:Building very large spreadsheet with PHPSpreadsheet使用 PHPSpreadsheet 构建非常大的电子表格
【发布时间】:2018-11-16 19:21:38
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: php excel memory phpspreadsheet


    【解决方案1】:

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

    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);
    

    【讨论】:

    • 不幸的是,速度成本很高,至少在我的经验中:(
    • 同意! PHPSpreadsheet 有一个转折点,因为它太慢而无法使用。这一点取决于所使用的缓存机制和您的机器。另一方面,Spout 提供近乎恒定的性能。
    • 我刚改成box/spout,在遇到这个问题后上面提到过。所以再见 phpSpreadsheet 大文件!
    【解决方案2】:

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

    您的选择非常有限:

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

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


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

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

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

    注意: 在解决 version 3 performance issues 之前,您可能希望坚持使用 2.7 版

    我没有尝试过的另一个选项是PHP_XLSXWriter。似乎和 spout 有类似的目标

    【讨论】:

    • 我试过box/spout,它非常适合处理非常大的ex​​cel文件,但它不完全支持样式/设置列宽/自动宽度/单元格合并。
    • 哇,我刚试过盒子/喷口,速度惊人。同样在 2021 年,它仍然保持不变。如果您不需要字体或边框的某些格式之外的花哨功能,那就太棒了!
    • box/spout 效果很好。超快速和超轻资源。但是,如果 db 查询是一个瓶颈(一次最多 5k,40k 条记录),您需要在 spout 上将默认情况下不可能的数据分块(您需要每次写入差异文件并复制它 - 这不会似乎最优化)
    猜你喜欢
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 2018-03-05
    • 1970-01-01
    • 2018-11-09
    • 1970-01-01
    • 1970-01-01
    • 2012-07-20
    相关资源
    最近更新 更多