2010-08-21 99 views
14

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 1078799 bytes) in D:\xampplite\htdocs\Scraper\PHPExcel\Reader\Excel2007.php on line 269如何解决内存越来越疲乏PHPExcel?

我的128M PHP内存限制很快就会耗尽,即使我只是想用PHPExcel打开一个小小的〜350 KB的excel文件。

虽然,我可以增加配置中的内存限制,但很高兴看到是否有任何替代方案来解决这个问题。

+4

找出在Excel中使用这么多的内存,然后修复它..... – SoapBox 2010-08-21 12:27:24

+1

@SoapBox:总之,PHPExcel - 它是一个真正的内存猪:(而且,它是一种复杂的库,所以发现(更不用说修复)一个错误是非常重要的,在最坏的情况下,回避这个问题并找到一些替代库可能会更容易 – Piskvor 2010-08-21 15:01:37

+2

成为微软认证的,它只需要知道如何重启机器。将释放被泄漏软件使用的内存 – 2010-08-21 16:46:15

回答

50

文件大小不在使用PHPExcel时对于工作簿文件来说是一个很好的方法。行数和列数(即单元格)更重要。

PHPExcel代码本身的占用空间为10到25MB,具体取决于正在访问的组件。

目前,工作簿中的每个单元平均需要1k的内存(没有任何缓存)或1.6k的64位PHP--我暂时假设32位PHP--因此(例如)a 8000行31列(248,000个单元)的工作表大约242MB。使用单元格缓存(例如php:// temp或DiskISAM)可以减少约三分之一,因此8000行×31列将需要大约80MB。

有许多可用来帮助您减少内存使用选项:

是否使用电池缓存与PHPExcel?

require_once './Classes/PHPExcel.php'; 

$cacheMethod = PHPExcel_CachedObjectStorageFactory:: cache_to_phpTemp; 
$cacheSettings = array(' memoryCacheSize ' => '8MB'); 
PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings); 

$objReader = PHPExcel_IOFactory::createReader('Excel2007'); 
$objPHPExcel = $objReader->load("test.xlsx"); 

如果你只需要访问您的工作表数据,并且不需要访问单元格格式,则可以禁用阅读从工作簿中的格式信息:

$objReader = PHPExcel_IOFactory::createReader('Excel2007'); 
$objReader->setReadDataOnly(true); 
$objPHPExcel = $objReader->load("test.xlsx"); 

如果您只需要访问一些,但不是所有工作簿中的工作表,您可以加载只有那些工作表:

$objReader = PHPExcel_IOFactory::createReader('Excel2007'); 
$objReader->setLoadSheetsOnly(array("Worksheet1", "Worksheet2")); 
$objPHPExcel = $objReader->load("test.xlsx"); 

,如果你只想工作表中读取某些细胞,你ç添加一个过滤器:

class MyReadFilter implements PHPExcel_Reader_IReadFilter 
{ 
    public function readCell($column, $row, $worksheetName = '') { 
     // Read title row and rows 20 - 30 
     if ($row == 1 || ($row >= 20 && $row <= 30)) { 
      return true; 
     } 

     return false; 
    } 
} 

$objReader = PHPExcel_IOFactory::createReader('Excel2007'); 
$objReader->setReadFilter(new MyReadFilter()); 
$objPHPExcel = $objReader->load("test.xlsx"); 

所有这些技术都可以显着减少内存需求。

+0

5年后:您的答案仍然是最新的? – robsch 2015-12-10 09:04:08

+0

@robsch - Excel文件在5年内未改变格式; PHP内存限制仍然是PHP内存限制5年; cell PHPExcel中仍然存在缓存和读取过滤器 – 2015-12-10 09:06:29

+0

很高兴知道。谢谢! – robsch 2015-12-10 09:13:12

1

如果你想知道,你可以使用xhprof。根据这个链接,你可以跟踪它的内存使用情况...

3

仅仅因为数据文件只有X字节,并不意味着它使用RAM的X字节。例如,$ _SESSION数组中的4K数据在加载时使用64K的ram。这取决于代码对这些数据所做的事情。正确的答案是增加公羊的数量。

此外,如果这是一个XLSX文件,它们是ZIP的XML文档。文本文件压缩比1/2更严格,因此您的350K XLSX文件很容易为1MB Excel文件。

+0

这是一个非常好的答案,我从中学到了。谢谢。 – Chris 2010-08-21 23:36:46

1

Xdebug是用于php的分析器/调试器,可以帮助您追踪内存使用情况和功能调用,找出问题所在。而且易于安装,大多数Linux发行版都将其存放在存储库中,“yum install xdebug”,“apt-get install xdebug”。

2

PHPExcel以内存泄漏而闻名。我建议你使用的需要是PHPExcel使用内存的一小部分如下:

1)阅读:PHP-Excel-Reader

2)写作:Pear Spreadsheet Excel Writer

+0

根据网站的链接“Spreadsheet_Excel_Writer is out过时并需要彻底重写。如果您想帮助完成这项任务,请与我们联系。 “ – Isius 2011-12-02 19:32:13

+0

PHP-Excel-Reader也适用于Excel 2007? – logan 2014-02-22 17:07:32

+0

写作:[PHP_XLSXWriter](https://github.com/mk-j/PHP_XLSXWriter)内存使用情况比PHPExcel低95% – velcrow 2014-04-16 20:44:43

1

你应该注意的一件事是空单元格。

我有同样的问题,只有800行数据和脚本甚至无法阅读。 无论是超时和内存不足错误,当任何一个被修复。

@Mark Ba​​ker对细胞的评论让我想到了。我注意到我有大量的空单元格,只把数据单元格复制到一个新的工作簿中,让它在一秒钟内运行。

希望这可以帮助别人。

0
$objReader = PHPExcel_IOFactory::createReader('Excel2007'); 
$objReader->setReadDataOnly(true); 
$objPHPExcel = $objReader->load("test.xlsx"); 

这多少代码是关于如何关闭PHPExcel读者足够

0

这篇文章会谈: How to close excel file in php-excel-reader 如果你同时打开多个Excel文件,但实际上并不需要他们都在同一时间,那么你可以尝试打开和关闭(即取消设置)每个文件的读者一个接一个。顺便说一句,读者使用相同的变量名就足够了“unsetting”操作。