Intereting Posts
Доступ к имени объекта JSON в PHP Каковы преимущества использования отношения «один к одному»? (Баз данных) Как добавить рейтинг в список сортировки в Magento 1.7 Больше параметра, чем ожидалось: нет ошибки в PHP? Как использовать fsockopen (), чтобы открыть соединение Telnet с паролем? Круглое форматированное значение времени до ближайшего получаса Поиск ссылок, соответствующих заданной строке в запросе xpath / domdocument PHP «Истек срок действия документа» после использования кнопки «Назад» Как скрыть расширение .html с URL-адреса веб-сайта Как я могу добавить подсказку с драйвером в процесс проверки magento onepage? категории wp-запроса и имеет тег получение mysql_insert_id () при использовании ON DUPLICATE KEY UPDATE с PHP Почему crypt () генерирует разные результаты? Как сбросить Mock-объект с помощью PHPUnit Как выводить результаты запроса MySQL, в котором используются псевдонимы?

PHPExcel занимает очень много времени, чтобы прочитать файл Excel

Я использую PHPExcel 1.7.8, PHP 5.4.14, Windows 7 и электронную таблицу Excel 2007. Электронная таблица состоит из 750 строк, столбцов от A до BW и имеет размер около 600 КБ. Это мой код для открытия электронной таблицы – довольно стандартный:

//Include PHPExcel_IOFactory include 'PHPExcel/IOFactory.php'; include 'PHPExcel.php'; $inputFileName = 'C:\xls\lspimport\GetLSP1.xlsx'; // Read your Excel workbook try { $inputFileType = PHPExcel_IOFactory::identify($inputFileName); $objReader = PHPExcel_IOFactory::createReader($inputFileType); $objReader->setReadDataOnly(true); $objPHPExcel = $objReader->load($inputFileName); } catch(Exception $e) { die('Error loading file "'.pathinfo($inputFileName,PATHINFO_BASENAME).'": '.$e->getMessage()); } //set active worksheet $objWorksheet = $objPHPExcel->setActiveSheetIndexbyName('Sheet1'); $j = 0; for($i = 2; $i < 3; $i++) { ... } 

В конце концов, я в конечном итоге хочу перебирать каждую строку в электронной таблице, но пока я совершенствую скрипт, я прохожу только через одну строку. Проблема в том, что выполнение этого скрипта занимает 30 минут. Я echo -сообщения после каждого раздела кода, чтобы я мог видеть, что обрабатывалось и когда, и мой скрипт в основном ждет 30 минут в этой части:

 $objPHPExcel = $objReader->load($inputFileName); 

У вас что-то неправильно настроено? Я не могу понять, почему загрузка электронной таблицы занимает 30 минут. Я ценю любую помощь.

У PHPExcel есть проблема с определением, где находится конец вашего файла excel. Скорее, Excel с трудом знает, где конец. Если вы коснетесь ячейки в A: 1000000, она думает, что ей нужно это прочесть.

В прошлом я сделал 2 вещи, чтобы исправить это:

1) Вырезать и пропустить данные, которые вам нужны, в новый файл excel. 2) Укажите точные размеры, которые вы хотите прочитать.

Изменить Как сделать вариант 2

 public function readExcelDataToArray($excelFilePath, $maxRowNumber=-1, $maxColumnNumber=-1) { $objPHPExcel = PHPExcel_IOFactory::load($excelFilePath); $objWorksheet = $objPHPExcel->getActiveSheet(); //Get last row and column that have data if ($maxRowNumber == -1){ $lastRow = $objWorksheet->getHighestDataRow(); } else { $lastRow = $maxRowNumber; } if ($maxColumnNumber == -1){ $lastCol = $objWorksheet->getHighestDataColumn(); //Change Column letter to column number $lastCol = PHPExcel_Cell::columnIndexFromString($lastCol); } else { $lastCol = $maxColumnNumber; } //Get Data Array $dataArray = array(); for ($currentRow = 1; $currentRow <= $lastRow; $currentRow++){ for ($currentCol = 0; $currentCol <= $lastCol; $currentCol++){ $dataArray[$currentRow][$currentCol] = $objWorksheet->getCellByColumnAndRow($currentCol,, $currentRow)->getValue(); } } return $dataArray; } 

К сожалению, эти решения не очень динамичны.

Обратите внимание, что современный файл excel – это просто zip с расширением xlsx. Я написал расширения для PHPExcel, которые распаковывают их, и изменяют некоторые файлы xml, чтобы получить виды поведения, которые я хочу.

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

Решено (для меня) – см. Примечание внизу этого сообщения

Я пытаюсь использовать практически идентичный код на выделенном четырехъядерном сервере с 16 ГБ ОЗУ, также работает аналогичные версии – PHPExcel 1.7.9 и PHP 5.4.16

Простое создание пустого читателя занимает 50 секунд!

 // $inputFileType is 'Excel5'; $objReader = PHPExcel_IOFactory::createReader($inputFileType); 

Загрузка электронной таблицы (1 лист, 2000 строк, 25 столбцов) Я хочу обрабатывать (только для чтения), а затем занимает 1802 секунды.

 $objReader->setReadDataOnly(true); $objPHPExcel = $objReader->load($inputFileName); 

Из различных типов считывателя я последовательно получаю тайминги для создания экземпляра, как показано ниже

 foreach(array( 'Excel2007', // 350 seconds 'Excel5', // 50 seconds 'Excel2003XML', // 50 seconds 'OOCalc', // 50 seconds 'SYLK', // 50 seconds 'Gnumeric', // 50 seconds 'HTML', // 250 seconds 'CSV' // 50 seconds ) as $inputFileType) { $objReader = PHPExcel_IOFactory::createReader($inputFileType); } 

Пиковое использование памяти составляло около 8 МБ … намного меньше, чем 250 МБ, доступный для этого скрипта.

Мое подозрение было, что PHPExcel_IOFactory::createReader($inputFileType) вызывал что-то в цикле, который очень медленный в PHP 5.4.x?

Однако чрезмерное время было связано с тем, как PHPExcel называет его имена классов и соответствующую структуру файлов. Он имеет автозагрузчик, который преобразует имена классов, такие как * PHPExcel_abc_def * в PHPExcel / abc / def.php для инструкции require. Хотя у нас был каталог классов PHPExcel, определенный в нашем пути include, наш собственный (уже определенный) автозагрузчик не смог обработать манипуляцию от имени класса до требуемого имени файла (он искал * PHPExcel_abc_def.php *). Когда файл класса не может быть включен, наш автозагрузчик будет циклически 5 раз с задержкой в ​​10 секунд, чтобы увидеть, обновляется ли файл и, следовательно, может стать доступным. Таким образом, для каждого класса PHPExcel, который необходимо загрузить, мы вводили задержку в 50 секунд, прежде чем попасть в собственный автозагрузчик PHPExcel, который требовал, чтобы файл был в порядке.

Теперь, когда у меня есть это решение, PHPExcel окажется действительно потрясающим.

Я использую последнюю версию PHPExcel (1.8.1) в проекте Symfony, и я также сталкивался с задержками времени при использовании метода $ objReader-> load ($ file). Задержки времени не были вызваны автозагрузчиком, а самим методом загрузки. Этот метод фактически считывает каждую ячейку на каждом листе. И так как мой рабочий лист данных составлял 30 столбцов по 5000 строк, потребовалось около 90 секунд, чтобы прочитать всю эту информацию на моем старом рабочем компьютере.

Я предположил, что реальная загрузка / считывание значений ячеек будет выполняться «на лету», как я их просил, но это похоже на небольшую серьезную переписывание кода PHPExcel, нет реальной возможности для этой начальной задержки времени загрузки.

Если вы знаете, что ваш файл – довольно простой файл excel, вы можете выполнять ручное чтение. Файл .xslx – это просто zip-архив с данными и структурой таблиц, хранящимися в xml-файлах. Этот скрипт взял меня с 60 секунд, используемых на PHPExcel, до 0,18 секунды.

 $zip = new ZipArchive(); $zip->open('path_to/file.xlsx'); $sheet_xml = simplexml_load_string($zip->getFromName('xl/worksheets/sheet1.xml')); $sheet_array = json_decode(json_encode($xml), true); $values = simplexml_load_string($zip->getFromName('xl/sharedStrings.xml')); $values_array = json_decode(json_encode($values), true); $end_result = array(); if ($sheet_array['sheetData']) { foreach ($sheet_array['sheetData']['row'] as $r => $row) { $end_result[$r] = array(); foreach ($row['c'] as $c => $cell) { if (isset($cell['@attributes']['t'])) { if ($cell['@attributes']['t'] == 's') { $end_result[$r][] = $values_array['si'][$cell['v']]['t']; } else if ($cell['@attributes']['t'] == 'e') { $end_result[$r][] = ''; } } else { $end_result[$r][] = $cell['v']; } } } } 

Результат:

 Array ( [0] => Array ( [0] => A1 [1] => B1 [2] => C1 ) [1] => Array ( [0] => A2 [1] => B2 [2] => C2 ) ) 

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