最近在做一个数据处理分析的项目,中间会用到导出Excel的功能,平时都是用PHPExcel进行导出工作,没出现问题,今天却发现生成的文件只有几百字节,而且还打不开,肯定是有问题了。
我又试了试导出几百条数据,没有问题,但是生成一个上万条的数据就不行了,难不成是PHPExcel有限制吗?也没听说过啊,看来应该是内存溢出了。
那就试试吧,首先把页面设置为永不超时,因为有时候处理大量数据的时候,还没有处理完数据就超时了,在PHP页面最上面添加下面的代码:
set_time_limit(0);
接着就是内存溢出问题,把内存限制设置高一些,在PHP页面继续添加如下代码:
ini_set("memory_limit", "1024M");
如果你电脑内存很大,你也可以改成2048M或者更大。经过上面的修改后,没有再出现问题了。
当然,对于处理大数据,PHPExcel也给出了一些解决办法,从1.7.3版本开始,它支持设置cell的缓存方式,也就意味着不仅仅只能存在内存中,还可以有其他办法。
单元格缓存是将所需PHPExcel内存单元格对象缓存到磁盘、memcache、MemoryGZip等,这样读取上会更耗时,但可以降低内存的消耗。PHPExcel_CachedObjectStorageFactory 这个类中提供了这几个单元格缓存:
const cache_in_memory = 'Memory'; const cache_in_memory_gzip = 'MemoryGZip'; #将单元格序列化后再进行Gzip压缩,然后保存在内存中 const cache_in_memory_serialized = 'MemorySerialized'; # 将单元格数据序列化后保存在内存中 const cache_igbinary = 'Igbinary'; #存储为紧密的二进制形式 const cache_to_discISAM = 'DiscISAM'; #缓存在临时的磁盘文件中,速度可能会慢一些 const cache_to_apc = 'APC'; #Alternative PHP Cache可选PHP缓存 const cache_to_memcache = 'Memcache'; #保存在memcache中 const cache_to_phpTemp = 'PHPTemp'; #保存在php://temp const cache_to_wincache = 'Wincache'; const cache_to_sqlite = 'SQLite'; const cache_to_sqlite3 = 'SQLite3';
MemorySerialized: 使用这种缓存方式,单元格会以序列化的方式保存在内存中,这是降低内存使用率性能比较高的一种方案。
MemoryGZip: 与序列化的方式类似,这种方法在序列化之后,又进行gzip压缩之后再放入内存中,这回跟进一步降低内存的使用,但是读取和写入时会有一些慢。
DiscISAM:当使用cache_to_discISAM这种方式时,所有的单元格将会保存在一个临时的磁盘文件中,只把他们的在文件中的位置保存在PHP的内存中,这会比任何一种缓存在内存中的方式都慢,但是能显著的降低内存的使用。临时磁盘文件在脚本运行结束是会自动删除。
PHPTemp: 类似cache_to_discISAM这种方式,使用cache_to_phpTemp时,所有的单元格会还存在php://temp I/O流中,只把 他们的位置保存在PHP的内存中。PHP的php://memory包裹器将数据保存在内存中,php://temp的行为类似,但是当存储的数据大小超 过内存限制时,会将数据保存在临时文件中,默认的大小是1MB,但是你可以在初始化时修改它。php://temp文件在脚本结束是会自动删除。
具体的用法:
$cacheMethod = \PHPExcel_CachedObjectStorageFactory::cache_in_memory_gzip; if (!\PHPExcel_Settings::setCacheStorageMethod($cacheMethod)) { die($cacheMethod . " 缓存方法不可用" . EOL); }
大家可以试试,找到适合自己的缓存方式。
有问题可在下方评论留言,或关注“大超小志”微信公众号留言。
留言评论
如需留言或评论,请在微信中打开此页面。