致命错误:第 269 行的 D:\xampplite\htdocs\Scraper\PHPExcel\Reader\Excel2007.php 中允许的内存大小为 134217728 字节已用尽(试图分配 1078799 字节)
即使我只是尝试使用 PHPExcel 打开一个 ~350 KB 的小型 Excel 文件,我的 128M PHP 内存限制也会很快耗尽。
虽然,我可以增加配置中的内存限制,但很高兴看看是否有任何替代方法可以解决这个问题。
致命错误:第 269 行的 D:\xampplite\htdocs\Scraper\PHPExcel\Reader\Excel2007.php 中允许的内存大小为 134217728 字节已用尽(试图分配 1078799 字节)
即使我只是尝试使用 PHPExcel 打开一个 ~350 KB 的小型 Excel 文件,我的 128M PHP 内存限制也会很快耗尽。
虽然,我可以增加配置中的内存限制,但很高兴看看是否有任何替代方法可以解决这个问题。
使用 PHPExcel 时,文件大小不是衡量工作簿文件的好方法。行数和列数(即单元格)更为重要。
PHPExcel 代码本身的占用空间在 10 到 25MB 之间,具体取决于正在访问的组件。
目前,工作簿中的每个单元格平均占用 1k 内存(没有任何缓存)或 1.6k 在 64 位 PHP 上 - 我暂时假设 32 位 PHP - 所以(例如)一个 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");
所有这些技术都可以显着降低内存需求。
仅仅因为数据文件只有 X 字节,并不意味着它使用 X 字节的内存。例如,$_SESSION 数组中只有 4K 的数据在加载时使用了 64K 的内存。它只取决于代码对这些数据做了什么。正确答案是增加ram的数量。
此外,如果这是一个 XLSX 文件,它们是 ZIP 格式的 XML 文档。文本文件的压缩比 1/2 小得多,因此您的 350K XLSX 文件很容易成为 1MB 的 Excel 文件。
如果您想找出答案,可以使用xhprof。根据此链接,您可以使用它跟踪内存使用情况...
Xdebug 是 php 的分析器/调试器,可以帮助您跟踪内存使用情况和函数调用以找出问题所在。而且它易于安装,大多数 linux 发行版都在存储库中,“yum install xdebug”,“apt-get install xdebug”。
您还应该注意的一件事是空单元格。
我有同样的问题,只有 800 行数据,脚本甚至无法读取。修复后的超时和内存不足错误。
@Mark Baker 关于细胞的一些说法让我开始思考。我注意到我有很多空单元格,并且只将带有数据的单元格复制到新工作簿中,它可以在一秒钟内运行。
希望这可以帮助某人。
$objReader = PHPExcel_IOFactory::createReader('Excel2007');
$objReader->setReadDataOnly(true);
$objPHPExcel = $objReader->load("test.xlsx");
这么多代码就够了
这篇文章讨论了如何关闭 PHPExcel 阅读器: 如何在 php-excel-reader 中关闭 excel 文件 如果您同时打开多个 Excel 文件,但实际上并不需要同时打开它们,那么您可以尝试打开并一个一个地关闭(即取消设置)每个文件的阅读器。顺便说一句,为读者使用相同的变量名称就足够了“取消设置”操作。