【问题标题】:Export large rows to Excel document, in small memory footprint将大行导出到 Excel 文档,占用较小的内存
【发布时间】:2011-10-10 17:00:03
【问题描述】:

我正在使用 PHPExcel 创建 Excel 文档,使用 MySQL 数据库中的数据。我的脚本必须在 512MB 的 RAM 中执行,我遇到了麻烦,因为我的导出记录达到 200k:

PHP 致命错误:允许的内存大小为...

如何使用 PHPExcel 在尽可能少的 RAM 中创建大型文档?

我当前的代码:

            // Autoload classes
    ProjectConfiguration::registerPHPExcel();


    $xls = new PHPExcel();
    $xls->setActiveSheetIndex(0);


    $i = 0; 
    $j = 2; 
            // Write the col names
    foreach ($columnas_excel as $columna) {
        $xls->getActiveSheet()->setCellValueByColumnAndRow($i,1,$columna);
        $xls->getActiveSheet()->getColumnDimensionByColumn($i)->setAutoSize(true);
        $i++;
    }


    // paginate the result from database
    $pager = new sfPropelPager('Antecedentes',50);
    $pager->setCriteria($query_personas);
    $pager->init();
    $last_page = $pager->getLastPage();

    //write the data to excel object
    for($pagina =1; $pagina <= $last_page; $pagina++) {
        $pager->setPage($pagina);
        $pager->init();
        foreach ($pager->getResults() as $persona) {
            $i = 0;
            foreach ($columnas_excel as $key_col => $columnas) {
                $xls->getActiveSheet()->setCellValueByColumnAndRow($i,$j,$persona->getByName($key_col, BasePeer::TYPE_PHPNAME));
                $i++;
            }
            $j++;
        }
    }

    // write the file to the disk
    $writer = new PHPExcel_Writer_Excel2007($xls);
    $filename = sfConfig::get('sf_upload_dir') . DIRECTORY_SEPARATOR . "$cache.listado_personas.xlsx";
    if (file_exists($filename)) {
        unlink($filename);
    }
    $writer->save($filename);

CSV 版本:

// Write the col names to the file
$columnas_key = array_keys($columnas_excel);
file_put_contents($filename, implode(",", $columnas_excel) . "\n");

//write data to the file
for($pagina =1; $pagina <= $last_page; $pagina++) {                     
        $pager->setPage($pagina);
        $pager->init();
        foreach ($pager->getResults() as $persona) {
            $persona_arr = array();
            // make an array        
            foreach ($columnas_excel as $key_col => $columnas) {
                $persona_arr[] = $persona->getByName($key_col, BasePeer::TYPE_PHPNAME);                 
            }
            // append to the file
            file_put_contents($filename, implode(",", $persona_arr) . "\n", FILE_APPEND | LOCK_EX);             
        }
    }

仍然存在RAM问题,当Propel向数据库发出请求时,就像Propel一样,每次发出新请求时都不会释放RAM。我什至尝试在每次迭代中创建和删除 Pager 对象

【问题讨论】:

  • 您是否考虑过创建一个 CSV,以便您可以随时写入文件?
  • 我为导出到 CSV 做了费用,但遇到了类似的问题

标签: php memory-management memory-leaks propel phpexcel


【解决方案1】:

Propel 在 Query API 中有formatters,你就可以写出这样的代码:

<?php
$query = AntecedentesQuery::create()
           // Some ->filter()
           ;
$csv = $query->toCSV();

$csv 包含一个 CSV 内容,您可以通过设置正确的 mime-type 来呈现。

【讨论】:

    【解决方案2】:

    既然您似乎可以使用 CSV,请尝试一次提取 1 条记录并将其附加到您的 CSV。不要尝试同时获取所有 200k 条记录。

    $cursor = mysql_query( $sqlToFetchData );    // get a MySql resource for your query
    $fileHandle = fopen( 'data.csv', 'a');       // use 'a' for Append mode
    
    while( $row = mysql_fetch_row( $cursor ) ){  // pull your data 1 record at a time
        fputcsv( $fileHandle, $row );            // append the record to the CSV file
    }
    
    fclose( $fileHandle );                       // clean up
    mysql_close( $cursor );
    

    我不知道如何将 CSV 转换为 XLS 文件,但希望这可以帮助您。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-19
      • 1970-01-01
      • 2019-11-21
      • 2014-12-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多