0

我使用 phpexcel 导出文件 xlsx,数据有 32 列和许多行。每天数据都在增加,所以数据会非常大。这是我的代码:

$filename="data.xlsx";
            $cacheMethod = PHPExcel_CachedObjectStorageFactory:: cache_to_phpTemp;
            $cacheSettings = array( 'memoryCacheSize' => '128MB');
            PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings);
            ini_set('max_execution_time', 123456);
            $objPHPExcel = new PHPExcel();
            $objPHPExcel->setActiveSheetIndex(0);
            $i = 2;
            $objPHPExcel->getActiveSheet()->setCellValue('A1', 'Header1');
            $objPHPExcel->getActiveSheet()->setCellValue('B1', 'Header2');
            $objPHPExcel->getActiveSheet()->setCellValue('C1', 'Header3');
            $objPHPExcel->getActiveSheet()->setCellValue('D1', 'Header4');
            $objPHPExcel->getActiveSheet()->setCellValue('E1', 'Header5');
            $objPHPExcel->getActiveSheet()->setCellValue('F1', 'Header6');
            $objPHPExcel->getActiveSheet()->setCellValue('G1', 'Header7');
            $objPHPExcel->getActiveSheet()->setCellValue('H1', 'Header8');
            $objPHPExcel->getActiveSheet()->setCellValue('I1', 'Header9');
            $objPHPExcel->getActiveSheet()->setCellValue('J1', 'Header10');
            $objPHPExcel->getActiveSheet()->setCellValue('K1', 'Header11');
            $objPHPExcel->getActiveSheet()->setCellValue('L1', 'Header12');
            $objPHPExcel->getActiveSheet()->setCellValue('M1', 'Header13');
            $objPHPExcel->getActiveSheet()->setCellValue('N1', 'Header14');
            $objPHPExcel->getActiveSheet()->setCellValue('O1', 'Header15');
            $objPHPExcel->getActiveSheet()->setCellValue('P1', 'Header16');
            $objPHPExcel->getActiveSheet()->setCellValue('Q1', 'Header17');
            $objPHPExcel->getActiveSheet()->setCellValue('R1', 'Header18');
            $objPHPExcel->getActiveSheet()->setCellValue('S1', 'Header19');
            $objPHPExcel->getActiveSheet()->setCellValue('T1', 'Header20');
            $objPHPExcel->getActiveSheet()->setCellValue('U1', 'Header21');
            $objPHPExcel->getActiveSheet()->setCellValue('V1', 'Header22');
            $objPHPExcel->getActiveSheet()->setCellValue('W1', 'Header23');
            $objPHPExcel->getActiveSheet()->setCellValue('X1', 'Header24');
            $objPHPExcel->getActiveSheet()->setCellValue('Y1', 'Header25');
            $objPHPExcel->getActiveSheet()->setCellValue('Z1', 'Header26');
            $objPHPExcel->getActiveSheet()->setCellValue('AA1', 'Header27');
            $objPHPExcel->getActiveSheet()->setCellValue('AB1', 'Header28');
            $objPHPExcel->getActiveSheet()->setCellValue('AC1', 'Header29');
            $objPHPExcel->getActiveSheet()->setCellValue('AD1', 'Header30');
            $objPHPExcel->getActiveSheet()->setCellValue('AE1', 'Header31');
            $objPHPExcel->getActiveSheet()->setCellValue('AF1', 'Header32');
            foreach ($data as $value) {
                $objPHPExcel->getActiveSheet()->setCellValue('A'.$i, $value['1']);
                $objPHPExcel->getActiveSheet()->setCellValue('B'.$i, $value['2']);
                $objPHPExcel->getActiveSheet()->setCellValue('C'.$i, $value['3']);
                $objPHPExcel->getActiveSheet()->setCellValue('D'.$i, $value['4']);
                $objPHPExcel->getActiveSheet()->setCellValue('E'.$i, $value['5']);
                $objPHPExcel->getActiveSheet()->setCellValue('F'.$i, $value['6']);
                $objPHPExcel->getActiveSheet()->setCellValue('G'.$i, $value['7']);
                $objPHPExcel->getActiveSheet()->setCellValue('H'.$i, $value['8']);
                $objPHPExcel->getActiveSheet()->setCellValue('I'.$i, $value['9']);
                $objPHPExcel->getActiveSheet()->setCellValue('J'.$i, $value['10']);
                $objPHPExcel->getActiveSheet()->setCellValue('K'.$i, $value['11']);
                $objPHPExcel->getActiveSheet()->setCellValue('L'.$i, $value['12']);
                $objPHPExcel->getActiveSheet()->setCellValue('M'.$i, $value['13']);
                $objPHPExcel->getActiveSheet()->setCellValue('N'.$i, $value['14']);
                $objPHPExcel->getActiveSheet()->setCellValue('O'.$i, $value['15']);
                $objPHPExcel->getActiveSheet()->setCellValue('P'.$i, $value['16']);
                $objPHPExcel->getActiveSheet()->setCellValue('Q'.$i, $value['17');
                $objPHPExcel->getActiveSheet()->setCellValue('R'.$i, $value['18']);
                $objPHPExcel->getActiveSheet()->setCellValue('S'.$i, $value['19']);
                $objPHPExcel->getActiveSheet()->setCellValue('T'.$i, $value['20']);
                $objPHPExcel->getActiveSheet()->setCellValue('U'.$i, $value['21']);
                $objPHPExcel->getActiveSheet()->setCellValue('V'.$i, $value['22']);
                $objPHPExcel->getActiveSheet()->setCellValue('W'.$i, $value['23']);
                $objPHPExcel->getActiveSheet()->setCellValue('X'.$i, $value['24']);
                $objPHPExcel->getActiveSheet()->setCellValue('Y'.$i, $value['25']);
                $objPHPExcel->getActiveSheet()->setCellValue('Z'.$i, $value['26']);
                $objPHPExcel->getActiveSheet()->setCellValue('AA'.$i, $value['27']);
                $objPHPExcel->getActiveSheet()->setCellValue('AB'.$i, $value['28']);
                $objPHPExcel->getActiveSheet()->setCellValue('AC'.$i, $value['29']);
                $objPHPExcel->getActiveSheet()->setCellValue('AD'.$i, $value['30']);
                $objPHPExcel->getActiveSheet()->setCellValue('AE'.$i, $value['31']);
                $objPHPExcel->getActiveSheet()->setCellValue('AF'.$i, $value['32']);
                $i++;
            }
            $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
            ob_end_clean();
            header("Content-type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            header("Content-Disposition: attachment; filename=".$filename);
            header('Cache-Control: max-age=0');
            $objWriter->setUseDiskCaching(true);
            $objWriter->save("php://output");

两天前,它运行良好。但是今天,它抛出了一个异常: 致命错误:第 155 行 /..../Classes/PHPExcel/CachedObjectStorage/CacheBase.php 中允许的内存大小为 134217728 字节已用尽(试图分配 85 字节)

4

2 回答 2

3

另外需要注意的是,您正在通过一个名为 $data.... 的数组循环来构建 PHPExcel 对象。我猜它是通过循环数据库查询的结果构建的。

该 $data 数组也将使用您的大部分内存,随着结果数量的增加,每天的内存越来越多。

如果不是循环通过数据库结果集来构建一个大数组,然后循环通过该数组来构建 PHPExcel 数据,而是循环通过数据库结果集并直接构建 PHPExcel 数据,那么效率会更高。这消除了 $data 的内存开销,并将 2 个循环减少到 1 个。

于 2013-10-20T10:49:08.227 回答
2

请记住,除了 PHPExcel 对象使用的内存之外,PHP 还使用内存以及脚本本身。

如果使用 memoryCacheSize 设置 cache_to_phpTemp,PHPExcel 对象将使用内存达到该限制,然后切换到使用临时文件。您的 memoryCacheSize 与您的绝对 php.ini 内存限制 (128MB) 相同,因此 PHPExcel 在达到 PHP 自己的限制之前永远不会切换到使用临时文件单元缓存。尝试设置较低的 memoryCacheSize(例如 64MB),这样至少 PHPExcel 将有机会缓存​​单元格并减少其自身的内存使用量。

于 2013-10-20T10:19:45.587 回答