Добрый день Подскажите, пожалуйста, чем лучше парсить файл xls. Файлы большие (~3мб, ~15к строк и строки есть длинные, больше 255 символов, если сохраняю файл как csv, то такие строки заменяются на #### и парсить csv уже не имеет смысла) Благодарен за ответ
PHPExcel! если нужны только данные из файла, то читать надо $reader->load(file, ReadDataOnly) чтобы не читались оформитеольские штучки. Эта возможность позволяет считывать в память только данные- меньше загружает память. можно парсить как по буквам, типа "А1", "B9", "F6276". А можно сделать что- то вроде $cells= $excel->activeSheet()->cellsAsArray() и получить массив ячеек, к которому можно обращаться по индексам $cell[1][2], $cells[6][21] и т.д. если завтра попросят перейти на xlsx, придется поменять всего одну строчку чтения файла в память, в весь "алгоритм парсинья" останется неизменным.
да в том то и дело, что не хватает перепробовал уже кучу парсеров, с небольшими файлами работают прекрасно, при тестировании этих же файлов, но увеличенных в разы по количеству записей вылетает скрипт нужен парсер который берет только данные, не смотрит и не запоминает ни шрифты ячеек таблицы, ни стили, ни форматирования, ни объединения, ни что-либо еще я не могу поставить какие-то ограничения на размер файла или количество строк в нем, скрипт используется предприятиями, которые грузят прайс-листы запчастей для техники (у кого-то 5к наименований, у кого-то 25к) служба поддержки хостинга рекомендовали использовать csv, но там при сохранении строки более 255 символов заменяются на ###, хоть таких строк и немного, но все равно это уже не вариант
а как делить на части ? если вылетает ошибка о нехватке памяти уже на открытии файла парсером. вариант предложить клиентам грузить прайсы по 5 тысяч записей несколькими файлами не подходит, уж слишком навязчивый сервис получится
Этот пробовал? http://sourceforge.net/projects/phpexcelreader/ Он у меня читает файлы по 15Мб (Памяти на сервере 4Гб)
ты мне скажи ReadDataOnly не забыл указать? если и это не помогает, то можно посоветовать только увеличить доступную скрипту память allowed_memory_size в php.ini. все остальные парсеры в лучшем случае сделают что PHPExcel при ReadDataOnly. Так что сколько с ними не экспериментируй- не заработает.
Беру свои слова обратно. PHPExcel и любая другая объектная библиотека не подходит для обработки таких файлов. Несложно посчитать если в файле 20к строк по 15 колонок, то получается 300 000 ячеек. если в каждой строчке по 500 символов да каждый символ в юникоде весит два байта, то данных там всего на 20Мб. 20 Мб- это конечно не много, но объектные библиотеки создают минимум по одному объекту на каждую ячейку. Даже если не читать оформления и пр. ненужности, все равно получается 300 000 тяжелых объектов. Если бы те же самые данные поместить в обычный массив в текстовом виде, это не требовало бы столько памяти. Поэтому для парсинья тысячников больше подойдет PHP-ExcelReader. Там как раз так все и устроено. например, данные хранятся вот так $xl_reader->sheets[0]['cells'][2][4] а PHPExcel протестил на 20k строках, в каждой 15 колонок, в одной из колонок число символов очень большое (до 400). Вот результат первый для ексель 2003, второй для 2007. В обоих случаях стоял $reader->setReadDataOnly(true) 11:22:04 Load from Excel2003 file 11:30:28 Peak memory usage: 278.75 MB 11:30:28 Done. 11:31:42 Load from Excel2007 file 11:38:33 Peak memory usage: 269 MB 11:38:34 Done. По этим данным можно расчитать максимальный размер экселевского файла, который можно парсить/генерить на хостинге при помощи PHPExcel. Например, если стоит ограничение памяти 128 Мб, то получится загрузить не больше 20*128/269= 9.5k строк по 15 колонок или 20k строк но по 7 колонок или 4k строк по 30 колонок и т.д. Вот такие вот ограничения. Если же задача такая, что больших объемов там не бывает, все равно PHPExcel, потому что объектный стиль- это все- таки не sheets[0]['cells'][2][4]
А вы не подскажите, чем вы сейчас парсите? Я сейчас изучаю это http://code.google.com/p/php-excel-reader/ , из всего того, что пробовал самая не требовательная к памяти, если подключать файл с параметром "false": Код (Text): $xls = new Spreadsheet_Excel_Reader("$fileXLS",false); Ещё в файле excel_reader2.php, можно закоментировать строки: Код (Text): if ($this->store_extended_info) { $this->sheets[$this->sn]['cellsInfo'][$row + $this->_rowoffset][$col + $this->_coloffset]['raw'] = $raw; $this->sheets[$this->sn]['cellsInfo'][$row + $this->_rowoffset][$col + $this->_coloffset]['type'] = $type; $this->sheets[$this->sn]['cellsInfo'][$row + $this->_rowoffset][$col + $this->_coloffset]['format'] = $format; $this->sheets[$this->sn]['cellsInfo'][$row + $this->_rowoffset][$col + $this->_coloffset]['formatIndex'] = $formatIndex; } это тоже сбережёт память, особенно если закоментированная инфа, вам не нужна. Скорее всего, вам ещё понадобится изменить кодировку, в моём случае так: Код (Text): var $_defaultEncoding = 'CP1251'; Одна проблема у меня ещё с этим скриптом осталась, почему-то не все форматы ячеек считываются, вместо некоторых значений получаю "GENERAL". Разбираюсь... Если вы тоже будите разбираться с этим скриптом и найдёте решение, отпишите здесь или в личку, буду весьма признателен.
Прошу прощения за некропостинг, но не смог самостоятельно решить проблему с кодировкой. Прописал: Код (Text): var $_defaultEncoding = 'CP1251'; Но все равно вместо русских букв выводятся каракули. В php.ini прописан windows-1251, в apache прописан UTF-8 (почему то с такой комбинацией меньше всего проблем, но я пробовал по всякому - не помогло). Очень надеюсь, что поможете решить данную проблему.
У меня тоже была проблема с кодировкой, вот так заработало: Код (Text): $data = new Spreadsheet_Excel_Reader(); $data->setOutputEncoding('CP1251'); $data->setUTFEncoder('mb'); $data->read("example2.xls");
привет всем... у меня все получилось.. кодировку на странице сделал - UTF-8 только 2(не русских, не англ.) символа заменяються на вопросики остальные показываються как есть вот пример - www.entonee.net/exel/example.php а вот и excel file - www.entonee.net/exel/jxlrwtest.xls ------- может кто подскажет изза чего это.......? спасибо
Создавать объект для каждой ячейки это действительно не очень хорошая идея, Excel_Spreadsheet_Reader прекрасно обходится без этого. Но если нужно всё равно перегнать всё в массив то можно просто заблокировать создание объекта ячейки. Для PHPExcel для чтения XLSX (Excel2007 reader) файлов я сделал маленький патч (злобный хак), там же образом ,думаю, можно оптимизировать другие ридеры. Решение с патчем загнал в их трекер. http://phpexcel.codeplex.com/workitem/14701 Расход по памяти уменьшился в 7 раз (было 88 МБ - стало 12 МБ для 5 МБ файла). Возможно есть более красивое решение, но __мою__ задачу этот патч (злобный хак) решает.
Подскажите, а есть какие-нибудь библиотеки для доступа к таблицам в Excel файле через SQL интерфейс? По типу как это реализовано в ODBC