Php 读取大型Excel 2007(.xlsx)时的内存
我用的是我以前用过很多次的。我现在遇到的问题是在读取Excel2007文件(.xlsx-format)时。我所做的只是循环Php 读取大型Excel 2007(.xlsx)时的内存,php,memory-management,out-of-memory,phpexcel,phpexcelreader,Php,Memory Management,Out Of Memory,Phpexcel,Phpexcelreader,我用的是我以前用过很多次的。我现在遇到的问题是在读取Excel2007文件(.xlsx-format)时。我所做的只是循环.xlsx文件,按行/列创建一个数组,然后在读取操作后打印结果,以确保数据输出良好,然后再将其导入MySQL数据库 现在,当读取Excel2007.xlsx文件(6MB)时,输出失败,但有趣的是,如果我将文件保存为较旧的格式.xls(1992-2004-Excel5),文件会变大(16MB),但输出正确。这让我觉得原来这不是内存问题,因为较旧的较大的.xls文件(16MB)运
.xlsx
文件,按行/列创建一个数组,然后在读取操作后打印结果,以确保数据输出良好,然后再将其导入MySQL数据库
现在,当读取Excel2007.xlsx
文件(6MB)时,输出失败,但有趣的是,如果我将文件保存为较旧的格式.xls
(1992-2004-Excel5),文件会变大(16MB),但输出正确。这让我觉得原来这不是内存问题,因为较旧的较大的.xls
文件(16MB)运行时没有问题,几乎是.xlsx
文件(6MB)的3倍
出于测试目的,我随后复制了.xlsx
(6MB)文件中30000行中的25行,创建了一个新的Excel2007.xlsx
,并针对较小的25行数据集运行导入,并正确输出。这让我认为这是一个内存问题,但它与.xlsx
格式有关
我在AmazonWeb服务上运行服务器,并且有(16核,30GB内存),所以我应该有足够的资源来运行这个操作
问题:为什么我的输出在读取较小的
.xlsx
文件和较大的.xls
文件时失败,但在读取较小的.xlsx
文件(25行)时成功
//PHP函数
function parse_xls($file){
ini_set('memory_limit','-1');
$type = PHPExcel_IOFactory::identify($file);
$reader = PHPExcel_IOFactory::createReader($type);
$reader->setReadDataOnly(true);
$xls = $reader->load($file);
$sheet = $xls->getActiveSheet();
$highestRow = $sheet->getHighestRow();
$highestColumn = $sheet->getHighestColumn();
$highestColumnIndex = PHPExcel_Cell::columnIndexFromString($highestColumn);
for($row=2; $row <= ($highestRow+2); $row++){
$import[$row] = [];
for($col=0; $col < $highestColumnIndex; $col++){
$result = $sheet->getCellByColumnAndRow($col, $row)->getValue();
array_push($import[$row],$result);
}
}
print_r($import);
die();
}
function parse_xls($file){
ini_集('内存限制','-1');
$type=PHPExcel\u IOFactory::identify($file);
$reader=PHPExcel\u IOFactory::createReader($type);
$reader->setReadDataOnly(true);
$xls=$reader->load($file);
$sheet=$xls->getActiveSheet();
$highestRow=$sheet->getHighestRow();
$highestColumn=$sheet->getHighestColumn();
$highestColumnIndex=PHPExcel_单元::columnIndexFromString($highestColumn);
对于($row=2;$row GetCellByColumnRow($col,$row)->getValue();
数组推送($import[$row],$result);
}
}
印刷(进口);
模具();
}
对于大文件,我使用chunkReadFilter
$iChunkSize=1000;
对于($iStartRow=$row_start;$iStartRow SetCreateReader();
$oChunkFilter=new chunkReadFilter();
$objReader->setReadFilter($oChunkFilter);
$oChunkFilter->setRows($iStartRow,$iChunkSize);
$objReader->setReadFilter($oChunkFilter);
$objReader->setReadDataOnly(true);
$objPHPExcel=$objReader->load($files['path']);
$objPHPExcel->setActiveSheetIndex($iList);
$sFromCell='A'.$iStartRow;
$aData=$objPHPExcel->getActiveSheet()->toArray(null、true、true、false、$sFromCell);
//空闲内存
未设置($objPHPExcel);
unset($objReader);
未设置($oChunkFilter);
//解析数据
foreach($sKey=>$aValue){
...
}
//实际数据行
if(计数($aData)<$iChunkSize){
未结算($阿达塔);
打破
}
未结算($阿达塔);
}
我一点也不知道!可能有很多原因……物理文件大小并不反映工作表/行/列的数量。单元格的内容、文件中不同样式的数量等都会影响内存需求……而且保存为xls很可能会消除工作表中未使用的样式或引用你到底在使用单元缓存吗?如果你在构建一个行/列的数组,那么你就大大增加了对内存的需求script@MarkBaker我刚刚发布了我编写的函数,您可以查看一下,也许您可以找到我遗漏的内容。$import
将需要大量内存…PHP数组非常占用资源…即使这样,您也可以使用PHPExcel工作表的toArray()
方法,而不是编写自己的循环,但这仍然是内存密集型的。您已经让它工作了,但这并不能真正回答问题,是吗?