可以在PHP中将大型csv文件写为xls表吗?

时间:2014-08-22 15:23:59

标签: php mysql excel csv laravel

所以我有一种情况需要为用户提供一个多表excel文档,其中每张表有数千行和~10列。数据来自多个MySQL查询。

目前使用“Laravel Excel”库来执行此操作,但它占用了太多内存并且给我带来了巨大的可伸缩性问题。

所以我有一个想法是使用MySQL OUTFILE在磁盘上写一组csv文件,每个工作表一个,然后创建一个xls文档,并将之前编写的csv数据写成xls中的工作表。

是否有一种方法可以完成将csv内容写入“批量”表单,而无需逐行迭代通过csv或使用大量内存(例如直接写入磁盘?)

感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

Excel文件格式(BIFF和OfficeOpenXML)不利于像CSV一样逐行编写,因为数据不是线性存储的。这意味着用于编写本机格式Excel文件的所有PHP库都必须在PHP内存中工作,以管理将数据写入该文件格式的顺序,这意味着它们将为更大量的数据消耗大量内存。

Laravel Excel是PHPExcel的包装器,它提供了一些减少内存使用的选项(例如,将单元数据缓存到磁盘或SQLite数据库而不是将其全部保存在PHP内存中),尽管执行速度很快。我不知道的是Laravel Excel是否提供调用以启用这些缓存方法,但我相信有一些选项可供您配置。

您在Linux平台上的替代方案是使用非PHP解决方案,如libXl或PUNO与Open / Libre Office

答案 1 :(得分:0)

我最近遇到了一个非常类似的问题。我的解决方案是使用非常轻量级的PHP库PHP_XLSXWriter。

您可以在此处找到它:https://github.com/mk-j/PHP_XLSXWriter

它会对输出进行流式传输,因此无需在内存中保留尽可能多的内容。

在我的使用案例中,我将“writeStream”方法拆分为三种方法:一种用于页眉和页脚,一种用于工作表内容(即实际行)。通过这种方式,我可以编写标题,然后使用Laravel的“分块”功能,使写入变得更加渐进。

时间略有增加,但执行脚本的内存从大约200Mb减少到15Mb以下!