Экспорт больших строк в документ Excel с небольшим объемом памяти - PullRequest
2 голосов
/ 10 октября 2011

Я использую PHPExcel для создания документа Excel, используя данные из базы данных MySQL.Мой сценарий должен выполняться в объеме менее 512 МБ ОЗУ, и у меня возникают проблемы, поскольку мой экспорт достигает 200 тыс. Записей:

Неустранимая ошибка PHP: допустимый объем памяти ...

Как я могу использовать PHPExcel для создания больших документов с минимальным объемом оперативной памяти?

Мой текущий код:

            // 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);             
        }
    }

По-прежнему возникает проблема с ОЗУ , когда Propel делает запросы к базе данных, это как Propel, не освобождает ОЗУ каждый раз, когда выНовый запрос.Я даже пытался создавать и удалять объект Pager в каждой итерации

Ответы [ 2 ]

1 голос
/ 09 декабря 2011

Propel имеет formatters в API запросов, вы сможете написать такой код:

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

$csv содержит CSV-контент, который вы сможете отобразить, установивправильный тип пантомимы.

0 голосов
/ 11 октября 2011

Поскольку оказывается, что вы можете использовать CSV, попробуйте извлечь по 1 записи за раз и добавить ее в CSV.Не пытайтесь получить все записи по 200 000 одновременно.

$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, но, надеюсь, это поможет вам.

...