【发布时间】:2015-04-15 09:33:22
【问题描述】:
我正在使用以下方法创建一个 excel 表:
- Codeigniter 2.2.1
- PHP 5.4.25
- Apache 2.4.7
- XAMPP 1.8.2
- PHPExcel 1.8.0
我正在从数据库中获取 35000 行(大部分为空),其中包含 79 列,并写入 Excel 文件 (Excel5)。
它适用于 30000 行,峰值内存使用量为 1.44GB,文件大小为 24MB。但是当我去 35000 它超时说,
致命错误:E:\XAMPP\htdocs\ProjectName\application\libraries\PHPExcel\Writer\Excel5\BIFFwriter.php 第 144 行内存不足(已分配 1780219904)(试图分配 17301483 字节)
当我创建 PHPExcel 对象时,它最终会使用大量内存并超时。我在 php.ini 文件中设置了 "memory_limit= -1" 和 "max_execution_time= 1000" 并在 PHPExcel 中尝试了不同的缓存存储方法。
我在控制器中的算法是这样的
public function write_controller() {
error_reporting(E_ALL);
ini_set("display_errors", 1);
ini_set('memory_limit', '-1'); //-1 for unlimited memory
$dir = "assets/output/";
//FIRST CHECK IF PREVIOUS FILE EXISTS OR NOT
$this->clear_directory($dir);
// Loading PHPExcel library
$this->load->library('PHPExcel');
$this->load->library('PHPExcel/IOFactory');
$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_phpTemp;
$cacheSettings = array('memoryCacheSize' => '5000MB', 'cacheTime' => '1000');
PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings);
//First Create the xls file and then insert rest of the data
$objPHPExcel = new PHPExcel();
$objPHPExcel->getProperties()->setTitle("export")->setDescription("none");
//activate sheet number 1
$objPHPExcel->setActiveSheetIndex(0);
//Setting font styles
$objPHPExcel->getActiveSheet()->getDefaultStyle()->getFont()->setName('Arial')->setSize(8)->setBold(false);
//Setting number format as TEXT
$objPHPExcel->getActiveSheet()->getDefaultStyle()->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_TEXT);
//Freezing first top row
$objPHPExcel->getActiveSheet()->freezePane('A2');
$objWorksheet = $objPHPExcel->getActiveSheet();
$row1 = 1;
$objWorksheet->setCellValueByColumnAndRow(0, $row1, "Site name");
$objWorksheet->setCellValueByColumnAndRow(1, $row1, "Vendor_1");
$objWorksheet->setCellValueByColumnAndRow(2, $row1, "Status");
$objWorksheet->setCellValueByColumnAndRow(3, $row1, "Easting");
$objWorksheet->setCellValueByColumnAndRow(4, $row1, "Northing");
$objWorksheet->setCellValueByColumnAndRow(5, $row1, "Sector_1");
.
.
.
//Rest of the 74 columns
$style = array(
'alignment' => array(
'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_CENTER,
'vertical' => PHPExcel_Style_Alignment::VERTICAL_CENTER)
);
$objWorksheet->getDefaultStyle()->applyFromArray($style);
$objWriter = IOFactory::createWriter($objPHPExcel, 'Excel5');
$saved_location ='assets/output/Piano11.xls';
$objWriter->save($saved_location);
//Now reading the saved xls file
$objReader = new PHPExcel_Reader_Excel5();
$newPHPExcel = $objReader->load($saved_location);
$newWorksheet = $newPHPExcel->getActiveSheet();
//Now insert rest of the data from Piano table which will come from database
$table_name = 'piano_test';
$query = $this->db->get('tbl_piano');
if (!$query) {
return false;
}
// Fetching the data from table
$fields = $query->list_fields();
$row = 2;
foreach ($query->result() as $data) {
set_time_limit(0);
$col = 0;
foreach ($fields as $field) {
$newWorksheet->setCellValueByColumnAndRow($col, $row, $data->$field); //<- This skips leading 0s
$col++;
}
$row++;
}
$newobjWriter = IOFactory::createWriter($newPHPExcel, 'Excel5');
$newobjWriter->save('assets/output/Piano11.xls');
echo 'Memory peak usage: <b>'.$this->convert(memory_get_peak_usage(true)).'</b><br/>';
gc_collect_cycles();//garbage collector
echo 'inserted.';
}
任何解决方案如何最大限度地减少内存使用和执行时间?或任何其他替代解决方案?或者我应该改变我的算法吗?
【问题讨论】:
-
清除内存,计算所需的数量与清除你可以清除的数量,然后使用 memory_limt davidwalsh.name/increase-php-memory-limit-ini_set... 这些都是我所需要的,我处理 80+gb 的地理数据库 .. 你会有内存泄漏什么的。有时最好对它进行批处理。检查您的 PHP 版本是否存在已知的内存泄漏,因为这种情况经常发生。试试airpair.com/php/fatal-error-allowed-memory-size 否则你可能不走运.. 它在某种程度上一直是个问题
-
当您在此脚本中创建多个 Writer 时,您可能希望在调用 Writer 的 save() 方法后取消设置
-
您可以看到我已将内存限制设置为-1,这是所有可能的内存分配。
标签: php codeigniter-2 phpexcel