较大文件的 PHPExcel 导出失败
Posted
技术标签:
【中文标题】较大文件的 PHPExcel 导出失败【英文标题】:PHPExcel Export for Larger Files fails 【发布时间】:2011-04-22 20:41:47 【问题描述】:我正在使用 phpExcel 库来生成基于 mysql 数据库的 excel 数据。 MySql 查询结果为 1,34,000 行。 Excel 在一张工作表上支持 65,536 行。所以让逻辑像
foreach($result 作为 $value) $val = array_values($value); 如果($rowscounter addRow($val,$rowscounter); 别的 $active_sheet++; $objPHPExcel->createSheet(); $objPHPExcel->setActiveSheetIndex($active_sheet); $rowscounter = 1; $行计数器++; // 传递头部 header("Content-Type: $mtype; charset=" . $objPHPExcel->sEncoding); header("Content-Type:application/octet-stream"); header("Content-Disposition: inline; filename=\"" . $filename . ".$ext\""); // 保存为 excel 2003 文件 $objWriter = IOFactory::createWriter($objPHPExcel,$objPHPExcel->sFileFormat); //echo "内存使用峰值:" . (memory_get_peak_usage(true) / 1024 / 1024) 。 "MB";退出; $objWriter->save('php://output');在一个工作表达到 65000 条记录后创建新工作表。
但它不起作用;不给出任何输出或错误。最初我认为是因为内存限制。但是当回显时,它显示峰值内存为 1400.5 MB,我使用 ini_set('memory_limit', '3500M');
将内存限制设置为 3500MB
您能否提出一些建议或替代方案?
【问题讨论】:
您能概括一下您对 PHPExcel 所做的更改吗?您正在引用诸如 $objPHPExcel->addRow() 之类的方法(我希望它与工作表而不是工作簿相关联)和诸如 $objPHPExcel->sFileFormat 之类的属性,它们不是 PHPExcel 库代码的一部分。 您是否尝试过调试以确定它是在 foreach() 循环中失败,还是在尝试写入文件时失败? 是的,马克,$objPHPExcel->addRow() 是我的函数,它只是使用 ->getActiveSheet()->setCellValueByColumnAndRow(); 是的 $objPHPExcel->sFileFormat 不是 PHPExcel 的一部分。它的自定义变量。以上代码可完美处理 10,000 条记录。 您认为这不是内存 - 虽然我的经验估计是每个单元格 1k(列 x 行)* 2 + 25MB - 但其他可能性包括达到超时限制。 【参考方案1】:您可能超过了 65,000 的限制,您将 $rowscounter 的初始值设置为多少? 1 还是 0(零)?我问它数组结果从索引 0(零)开始的原因是,您要添加行,然后在添加后递增计数器。因此,如果您从 0(零)开始计数器,那么您可能会拥有比您计算的更多的行。此外,您在 else 语句中缺少一行,您遍历一个值但不将其添加到工作表中
试试这个
$rowscounter = 1;
foreach($result as $value)
$val = array_values($value);
if($rowscounter < 65000)
$objPHPExcel->addRow($val,$rowscounter);
else
$active_sheet++;
$objPHPExcel->createSheet();
$objPHPExcel->setActiveSheetIndex($active_sheet);
$rowscounter = 1;
// add missing row
$objPHPExcel->addRow($val,$rowscounter);
$rowscounter++;
// deliver header
header("Content-Type: $mtype; charset=" . $objPHPExcel->sEncoding);
header("Content-Type:application/octet-stream");
header("Content-Disposition: inline; filename=\"" . $filename . ".$ext\"");
// Save it as an excel 2003 file
$objWriter = IOFactory::createWriter($objPHPExcel,$objPHPExcel->sFileFormat);
//echo "Peak memory usage: " . (memory_get_peak_usage(true) / 1024 / 1024) . " MB";exit;
$objWriter->save('php://output');
我试图解释的一个简单示例,如果 $i 设置为 0(零),则不满足 else 条件。因此,您的结果中会多出一行。如果 $i 设置为 1 则满足 else 条件
$count = array(1,2,3,4,5,6,7,8,9,10);
$i=1; // set this to 0 (zero) and test, set to 1 and test
foreach($count as $cnt)
if($i < 10)
echo "If condition - Count value: ".$cnt." i value:".$i."<br />";
else
echo "Else condition - Count value: ".$cnt." i value:".$i."<br />";
$i++;
【讨论】:
嗨菲尔,是的,我错过了行。感谢识别逻辑错误。现在问题是内存问题。由于显示任何内容所需的时间太长,因此很难确定它的确切内存量。我试过分配35000M,还是没有效果。 发现了一个关于 PHPExcel 是内存泄漏问题的有趣线程:phpexcel.codeplex.com/Thread/View.aspx?ThreadId=18404 它确实有一个解决方法以上是关于较大文件的 PHPExcel 导出失败的主要内容,如果未能解决你的问题,请参考以下文章