PHPExcel проблема с памятью - PullRequest
8 голосов
/ 11 августа 2011

Я пытаюсь перебрать 3-мегабайтный документ Excel, чтобы получить все данные, которые мне затем нужно будет вставить в базу данных.Рабочая таблица, которую я использую, содержит 6500 строк, но в будущем она может измениться.Я заметил, что, хотя я использую рекомендуемые методы экономии памяти, он все равно срабатывает при

$reader = PHPExcel_IOFactory::createReaderForFile($file_path);
$reader->setReadDataOnly(true);

//$sheets = $this->getWorksheetNames($file['tmp_name'], 0);
$reader->setLoadSheetsOnly('spreadsheetname');

$chunkFilter = new IPO_Reader(); 
$reader->setReadFilter($chunkFilter); 

$highestRow    = 10000; //$this->objWorksheet->getHighestRow();
$chunkSize     = 1; 
$highestColumn = "Y";

for ($startRow = 2; $startRow <= $highestRow; $startRow += $chunkSize) 
{ 

    $chunkFilter->setRows($startRow, $chunkSize); 
    $objPHPExcel  = $reader->load($file_path); 

    for($row = $startRow ; $row <= $startRow + $chunkSize; $row++)
    {
        $this->read_row = $objPHPExcel->getActiveSheet()->rangeToArray('A'.$row.':'.$highestColumn.$row, null, true, true, true);

        $this->read_row = end($this->read_row);         

        foreach($this->read_row as $column => $value)
        {
            $db_column_name = $this->_getDbColumnMap($column);
            if(!empty($db_column_name))
            {
                $this->new_data_row[$db_column_name] = $this->_getRowData($value, $column);
            }   

        }

        $this->read_row = null;
        $this->new_data_row['date_uploaded']    = date("Y-m-d H:i:s");
        $this->new_data_row['source_file_name'] = $file_name;
        $ipo_row  = new Model_UploadData_IPO();
        $ipo_row->create($this->new_data_row);
        $this->new_data_row = null;
        unset($ipo_row);

        gc_collect_cycles();

    }
    $objPHPExcel->disconnectWorksheets(); 
    unset($objPHPExcel);    
    gc_collect_cycles();

, когда я проверяю использование памяти перед тем, как сбросить objPHPExcel, и после этого нет увеличенияЯ действительно в замешательстве, так как разделение на куски, кажется, не позволяет мне очищать память после каждого чанка, и использование постепенно увеличивается, и с ограничением, установленным в 250 МБ, это позволяет мне добавлять только ~ 500 записей

Ответы [ 2 ]

3 голосов
/ 13 августа 2011

Известно, что в библиотеке PHP Excel есть проблемы с памятью , у меня также были проблемы с этим. Для меня сработал этот совет (из приведенной выше ссылки попробуйте, есть хорошие советы, как уменьшить использование памяти):

$objReader = new PHPExcel_Reader_Excel5();
$objReader->setReadDataOnly(true); /* this */

Но в любом случае требования к памяти велики, потому что они выделяют много памяти для каждой ячейки (для форматирования и т. Д., Даже если это не нужно). Боюсь, мы беспомощны, пока не выпустят новую версию библиотеки.

0 голосов
/ 22 сентября 2011

Хорошо, все знают, что trwtf - это Excel, поэтому могу ли я спросить, можно ли преобразовать это в CSV?

У меня есть свои собственные функции CSV для таблиц в PHP, которые используются для импорта очень больших файлов, CSV, как правило, гораздо легче обрабатывать, а также гораздо менее подвержены случайным библиотекам.

Если вам действительно это нужно для одноразового процесса или вы можете довольно легко перейти от XLS к CSV, сделайте это, поскольку это значительно облегчит вашу жизнь (как каждый раз, когда вы придерживаетесь более простых, более стандартных альтернатив;)).

И поэтому для API, который будет переводить ужасный и ужасный формат XLS, вы можете использовать один из следующих o / s преобразователей - я бы порекомендовал python каждый раз, но, эй, ваш выбор:

http://www.oooninja.com/2008/02/batch-command-line-file-conversion-with.html

http://code.google.com/p/jodconverter/wiki/FAQ

По сути, идея та же: вы используете внешний инструмент, чтобы получить формат файла, который можно использовать, и затем вы идете оттуда.

Я не думаю, что у меня здесь есть мой скрипт csvtotable.php, но его довольно легко скопировать, вам просто нужно иметь несколько базовых инструментов, таких как csvtoarray и затем arraytoinsertstatements.

GL;)

...