Как исправить память, израсходованную с помощью PHPExcel?

Неустранимая ошибка: допустимый размер памяти 134217728 байт исчерпан (пытался выделить 1078799 байт) в D:\xampplite\HTDOCS\Скребок\PHPExcel\чтения\Excel2007.php on line 269

Мой предел памяти 128M PHP быстро исчерпывается, даже когда я только пытаюсь открыть небольшой файл excel ~ 350 КБ с помощью PHPExcel.

Хотя, я могу увеличить ограничение памяти в конфигурации, но будет здорово увидеть, есть ли какие-либо альтернативы для исправления этого.

Ответы

Ответ 1

Размер файла не является хорошей мерой для файлов книг при работе с PHPExcel. Число строк и столбцов (т.е. ячеек) более важно.

Сам код PHPExcel имеет размер от 10 до 25 МБ, в зависимости от того, к каким компонентам обращаются.

В настоящее время каждая ячейка в рабочей книге занимает в среднем 1 тыс. памяти (без кэширования) или 1,6 тыс. на 64-битном PHP - я буду предполагать 32-битный PHP на данный момент - так (например) рабочий лист из 8000 линий с 31 столбцом (248 000 ячеек) будет составлять около 242 МБ. С кэшированием ячеек (например, php://temp или DiskISAM), которые могут быть уменьшены примерно до трети, поэтому для 8000 строк по 31 столбцам потребуется около 80 МБ.

Существует ряд опций, которые помогут вам уменьшить использование памяти:

Используете ли вы кеширование ячеек с помощью PHPExcel?

require_once './Classes/PHPExcel.php';

$cacheMethod = PHPExcel_CachedObjectStorageFactory:: cache_to_phpTemp;
$cacheSettings = array( ' memoryCacheSize ' => '8MB');
PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings);

$objReader = PHPExcel_IOFactory::createReader('Excel2007');
$objPHPExcel = $objReader->load("test.xlsx");

Если вам нужно только получить доступ к данным на ваших листах и ​​не нуждаться в доступе к форматированию ячейки, вы можете отключить чтение информации форматирования из книги:

$objReader = PHPExcel_IOFactory::createReader('Excel2007');
$objReader->setReadDataOnly(true);
$objPHPExcel = $objReader->load("test.xlsx");

Если вам нужно только получить доступ к некоторым, но не ко всем листам в книге, вы можете загрузить только те рабочие листы:

$objReader = PHPExcel_IOFactory::createReader('Excel2007');
$objReader->setLoadSheetsOnly( array("Worksheet1", "Worksheet2") );
$objPHPExcel = $objReader->load("test.xlsx");

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

class MyReadFilter implements PHPExcel_Reader_IReadFilter
{
    public function readCell($column, $row, $worksheetName = '') {
        // Read title row and rows 20 - 30
        if ($row == 1 || ($row >= 20 && $row <= 30)) {
            return true;
        }

        return false;
    }
}

$objReader = PHPExcel_IOFactory::createReader('Excel2007');
$objReader->setReadFilter( new MyReadFilter() );
$objPHPExcel = $objReader->load("test.xlsx");

Все эти методы могут значительно снизить требования к памяти.

Ответ 2

Просто потому, что файл данных - это только X байтов, не означает, что он использует X байтов RAM. Например, только 4K данных в массиве $_SESSION использует 64K RAM при загрузке. Это просто зависит от того, что делает код с этими данными. Правильный ответ заключается в увеличении количества бара.

Также, если это файл XLSX, это ZIP-документы XML. Текстовые файлы zip up намного жестче, чем 1/2, поэтому ваш файл 350K XLSX легко представляет собой файл Excel 1MB.

Ответ 3

PHPExcel известен утечками памяти. Я советую вам использовать следующее: ФРАКЦИЯ памяти, используемой PHPExcel.:

1) Для чтения: PHP-Excel-Reader

2) Для написания: Pear Spreadsheet Excel Writer

Ответ 4

Если вы хотите узнать, вы можете использовать xhprof. Согласно этой ссылке вы можете отслеживать использование памяти с ней...

Ответ 5

Xdebug является профилировщиком/отладчиком для php и может помочь вам отслеживать использование памяти и функциональные вызовы, чтобы выяснить, в чем проблема. И его легко установить, большинство дистрибутивов Linux имеют его в репозитории, "yum install xdebug", "apt-get install xdebug".

Ответ 6

Одной вещью, которую вы должны заметить, также являются пустые ячейки.

У меня была такая же проблема, только 800 строк данных и script были даже не в состоянии читать. Как таймауты, так и ошибки в памяти, если они были исправлены.

Что-то @Mark Бейкер сказал, что клетки заставляют меня думать. Я заметил, что у меня было множество пустых ячеек и копирование только ячеек с данными в новую книгу заставил его запустить за секунду.

Надеюсь, это поможет кому-то.

Ответ 7

$objReader = PHPExcel_IOFactory::createReader('Excel2007');
$objReader->setReadDataOnly(true);
$objPHPExcel = $objReader->load("test.xlsx");

Этот много кода достаточно

Ответ 8

В этом сообщении говорится о том, как закрыть PHPExcel-ридер: Как закрыть файл excel в php-excel-reader Если вы одновременно открываете несколько файлов Excel, но на самом деле им не нужны все одновременно, вы можете попытаться открыть и закрыть (то есть отключить) считыватели для каждого файла один за другим. Btw, используя одно и то же имя переменной для читателей, было бы достаточно для операции "сбрасывания".