[ОБНОВЛЕНО 14.08.2010] Импорт материалов из XLS

Прислано: reynholm

чт, 12/08/2010 - 06:28

Для одного из проектов возникла необходимость в модуле импорта товаров из XLS файликов.
Требования были достаточными, что бы отказаться от использования уже готовых модулей и написать свой:
1. Требовалось учитывать рубрику каталога, к которому привязывался товар. К каждому товару указывался полный путь по каталогу: Оптика|Бинокли|Бинокли Pentax. Если какой-то раздел не существует, то должен создаваться.
2. В xls табличке для каждого товара указывается список картинок. Просто имена файлов, которые до (или после) импорта закидываются в папку на сервере: img1.jpg|img2.jpg
3. Возможность импорта в режиме замены, либо обновления. При замене сначала полностью удаляются старые товары, потом добавляются новые. При обновлении имеющиеся обновляются, новые добавляются, ничего не удаляется :)

Что в итоге получилось:
Пункты 1-3 соблюдены.
4. Добавлена возможность указать свой разделитель для множественных значений (да, в каждое поле можно по несколько значений импортировать).
5. Сопоставление полей материала и колонок xls таблицы сохраняются, а так же режим импорта сохраняются. Если прайс не меняется, то достаточно настроить 1 раз.
6. Зависимость модуля от Таксономии и ССК на самом деле не обязательна, с минимальными изменениями можно и в голый Друпал материалы импортировать.
7. Для анализа XLS использовалась библиотека PHPExcel. Благодаря этому опять же с минимальными изменениями можно загружать из XLSX, ODF, CSV.
8. Импорт идет по шагам, количество строк для импорта за 1 шаг настраивается. Можно использовать для импорта больших листов даже на слабых виртуальных серверах, не опасаясь вылета по времени выполнения или переполнения памяти.

Из минусов:
- откровенно поленился сделать пошаговость импорта через AJAX, без перезагрузки страницы;
- проверка входных данных идет без пристрастия; если картинка указана, а реально на сервер не загружена - ошибки не будет;
- возможности отложенного(по расписанию) импорта нет;
- совершенно не учитывается возможность одновременного импорта разными пользователями;
- еще 5000 минусов, которые найдете (сообщите о них, пожалуйста).

Внимание!
Для работы модуля требуется библиотека PHPExcel, ее можно взять тут, а сложить надо в папку phpexcel модуля.

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

Обновление [14.08.2010]:
Исправлена критическая ошибка, приводящая в некоторых случаях к бесконечной рекурсии. Пожалуйста, кто уже скачивал - обновите.

Прикрепленный файлРазмер
sample.xls14.5 кб
rimport.zip6.83 кб

Комментарии


Настройки просмотра комментариев

Выберите нужный метод показа комментариев и нажмите "Применить"
Опубликовано orangeudav в чт, 12/08/2010 - 07:17.

ваш случай - обычный csv файл , зачем было огород городить? node_import бы справился

вы попробуйте вот такой прайс автоматически обработать! (см аттач)


Опубликовано reynholm в чт, 12/08/2010 - 07:57.

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

По делу:
- node_import по-другому работает с таксономией;
- зачем заставлять клиента совершать лишние движения с сохранением в CSV (как, кстати, сейчас дела обстоят с загрузкой CSV в cp1251)?


Опубликовано igor701 в чт, 12/08/2010 - 08:01.

Прикольно, спасибо! Возьму на заметку.

P.S. А для указанного "навороченного" прайса надо индивидуальный парсер писать. И проблема, ИМХО, только в вырезании картинок.


Опубликовано orangeudav в чт, 12/08/2010 - 08:41.

индивидуальный парсер ... и вот у нас 20 поставщиков и у каждого свой формат прайслиста, сколько парсеров написать придется?

дергать картинки из ODS как раз несложно, спецификация открытая на формат (xml), мне пришлось один раз, и что самое приятно - они просто лежат файлами отдельными внутри документа openoffice, надо только в документе найти соотвествие между именем файла и местом где он используется.


Опубликовано reynholm в чт, 12/08/2010 - 10:47.

Я имел в виду, что из XLS мазохизм. Из ODS, ODF и XLSX как раз приятно - это же архив с xml файлами и всеми вложениями.

Вообще для случая как у вас просто деваться больше некуда. 20 абсолютно разных форматов листов.. Тут либо пресеты какие-то делать для одного парсера, либо пытаться договориться с поставщиками. Кстати, спасибо за пример, вечером поэкспериментирую с объединенными ячейками.


Опубликовано VasyOK в чт, 12/08/2010 - 11:30.

Выражаю благодарность за ваш общественно полезный труд!
Будет время обязательно посмотрю ваш модуль.

То что импорт можно провидить прямо из Excel файла - это очень удобно, т.к. Open Office медленный и не такой удобный.

С другой стороны при использовании модуля Node Import, есть возможность также использовать модуль Node export - ведь забивать товары ценами (для одного сайта) могут люди из разных городов. И это все может происходить непосредстсвенно на сайте, а не через импорт табличного файла.

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


Опубликовано volocuga@drupal.org в чт, 12/08/2010 - 13:06.

"reynholm" написал(а):

Можно использовать для импорта больших листов даже на слабых виртуальных серверах, не опасаясь вылета по времени выполнения или переполнения памяти.

А как это сделано?
xls разве можно построчно парсить?

Спасибо скажу и я, однако же если бы он был заточен под Уберкарт, с поддержкой атрибутов и прочего - это была бы реальная бомба. Просто мечтаю :)


Опубликовано RxB в чт, 12/08/2010 - 13:10.

"volocuga@drupal.org" написал(а):

Спасибо скажу и я, однако же если бы он был заточен под Уберкарт, с поддержкой атрибутов и прочего - это была бы реальная бомба.

А ты выложи прайс с атрибутами, глядишь кто-то и заточит, так как видение сабжа программистом может очень отличаться от реальности


Опубликовано reynholm в чт, 12/08/2010 - 13:14.

Распарсить xls можно сразу целиком весь, что собственно и делается. Полученная информация складывается в кеш. На эти операции много ресурсов и времени не требуется (phpexcel ограничивает размер файла семью мегабайтами, но даже такой объем сложно представить).
А вот добавление - процесс тяжелый, как раз он выполняется пошагово.

Пару лет назад писал импорт из xls в друпал 5 и уберкарт, но там ни о какой универсальности речи не шло. Заранее предопределенная схема прайса, известные поля товаров и тд и тп. Как следствие никаких настроек. Если вам чем-то поможет, исходниками могу поделиться.


Опубликовано VasyOK в чт, 12/08/2010 - 13:42.

Этот материал помещен на главную. Значит модератор здесь все таки есть... А кто это?


Опубликовано RxB в чт, 12/08/2010 - 13:44.

Если сможешь зайти сюда http://drupal.ru/node/48391/revisions то увидешь, у меня не работает


Опубликовано reynholm в чт, 12/08/2010 - 13:57.

"VasyOK" написал(а):

Этот материал помещен на главную. Значит модератор здесь все таки есть... А кто это?

Есть подозрение, что они: http://drupal.ru/ru_team =)


Опубликовано F10 в чт, 12/08/2010 - 17:06.

"reynholm" написал(а):

При обновлении имеющиеся обновляются, новые добавляются, ничего не удаляется :)

- что является ключем(как определяет что это не другая нода)?


Опубликовано reynholm в чт, 12/08/2010 - 17:48.

Заголовок (title).


Опубликовано Splinter в чт, 12/08/2010 - 19:45.

Спасибо, надо будет потестить!


Опубликовано orangeudav в чт, 12/08/2010 - 20:15.

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


Опубликовано chayka в сб, 14/08/2010 - 12:42.

Здравствуйте, совсем недавно стала осваивать друпал в качестве пользователя, может быть глупый вопрос, но спросить больше не у кого. Пытаюсь подключить этот модуль, но на странице подключения модулей, рядом с модулем rimport пишется "Зависит от: Taxonomy (включен), Cck (отсутствует)". CCK у меня подключен, причем все имеющиеся галочки. В чем может быть проблема?


Опубликовано reynholm в сб, 14/08/2010 - 13:22.

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

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


Опубликовано Artu в вт, 17/08/2010 - 13:05.

Полезный модуль.

Разве node_import умеет работать в режиме обновления?


Опубликовано VasyOK в ср, 18/08/2010 - 11:40.

Не умеет, но можно научить.


Опубликовано S_F в чт, 19/08/2010 - 22:10.

Node import в последней редакции умеет обновлять (она не на друпалорге), но у него есть другие траблы. А именно он как то откровенно паршиво работает с количеством на складе. Проблему пока разрешить не удалось, если кто сможет помочь, буду признателен.

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

Может это у меня какие проблемы с сайтом? а то ни один из модулей импорта не хочет работать..


Опубликовано Artu в пт, 20/08/2010 - 04:14.

>>(она не на друпалорге)
А где?


Опубликовано reynholm в пт, 20/08/2010 - 09:27.

«Потестил это модуль, после выбора файла и нажатия кнопки "отправить" моментально выдает ошибку страницы и все.
Может это у меня какие проблемы с сайтом? а то ни один из модулей импорта не хочет работать..»

А можно текст ошибки? Если ни один модуль импорта не работает, то, возможно, дело просто в отсутствии прав на запись в папку, т.е. модули не могут файлик закачать.


Опубликовано S_F в пт, 20/08/2010 - 10:10.

Нема текста ошибки, выдает стандартную браузерную "страница не найдена".

"прокаченый" ноде импорт в нескольких версиях под уберкарт растет тут:
http://www.ubercart.org/project/node_import_uc_stock

PS
Ребята, если кто будет тестить и все нормально заработает, дайте знать. Для меня очень важно пофиксить проблемы и заставить все это работать.


Опубликовано restyler в сб, 21/08/2010 - 17:05.

Комментарии чисто по коду -
вместо мешанины хтмла лучше использовать Form API, и t("Русский текст"); - так обычно не делают, в t оборачивается английский текст.


Опубликовано reynholm в сб, 21/08/2010 - 19:50.

На мой английский медведь в детстве наступил, поэтому русский.
Form API - согласен конечно, мешанина - не соответствует стандартам кодирования, принятым в Drupal. Но лично для меня реализовать форму выбора полей\колонок на Form API слишком проблематично. Зато есть к чему стремиться.
Спасибо за замечания.


Опубликовано RoSk0 в вс, 22/08/2010 - 20:20.

надо обязательно посмотреть! Огромное спасибо за OpenSource! Стоит такая же задача, но взяться за ее решение смелости не хватает, может с Вами заодно толк выйдет


Опубликовано razlivan в пн, 23/08/2010 - 09:13.

Попробовал вчера. По инструкции положил PHPExcel в папку sites/all/rimport/phpexcel Сразу же ругается на отсутствие файла PHPExcel.php У меня этот файл находится в папке sites/all/modules/rimport/phpexcel/Classes/ (Напишите, пожалуйста, какие файлы где должны находиться для правильной работы модуля) Если перенести его в /rimport/phpexcel/ начинает работать, но появляются следующие ошибки:

warning: rename(c:\windows\tempbook1.xls,c:\windows\temp2010.08.23.xls) [function.rename]: No such file or directory in .../public_html/sites/all/modules/rimport/rimport.module on line 187.

warning: Invalid argument supplied for foreach() in .../public_html/sites/all/modules/rimport/rimport.module on line 303.


Опубликовано reynholm в пн, 23/08/2010 - 13:14.

У вас, судя по всему, какая-то другая версия PHPExcel. В той, которую я качал папки Classes нет вообще, а файлик PHPExcel.php лежал в корне архива.


Опубликовано RoSk0 в пн, 23/08/2010 - 19:17.

"razlivan" написал(а):

Если перенести его в /rimport/phpexcel/ начинает работать, но появляются следующие ошибки:

Все правильно с phpExcell, проблема с правами на запись в каталог или сам каталог неправильно указали в настройках.

2reyholh Еще раз спасибо, что сделали свой труд достоянием общественности!


Опубликовано RoSk0 в ср, 25/08/2010 - 08:08.

Думаю логику надо пересмотреть. Хотя конечно все субъективно. Вы избаляясь отлишних пробелов удаляете пустые ячейки что может нарушить структуру файла. Ведь совсем не обязательно все ячейки должны иметь значения, возможно некоторые могут быть пыстыми, в этом случае Ваш модуль беспощадно исказит структуру файла и правильный маппинг будет просто невозможен.

Если я не ошибаюсь то для этого понадовиться исправить всего одну строку №205 в файле rimport.module

<?php
     $cellIterator
->setIterateOnlyExistingCells(true);
на 
     $cellIterator
->setIterateOnlyExistingCells(false);
?>


Опубликовано reynholm в ср, 25/08/2010 - 10:11.

Совершенно верно, столкнулся уже с этим. Огорчает полное отстутствие вразумительного описания API PHPExcel.
Спасибо.

В следующей версии исправлю и это.


Опубликовано RoSk0 в ср, 25/08/2010 - 11:45.

я был почти прав. Ошибка кроется в этих трех строках(204-206)

$cellIterator = $row->getCellIterator();
$cellIterator->setIterateOnlyExistingCells(true);
foreach($row->getCellIterator() as $cell){

Для того чтобы принимать во внимание пустые строки необходимо исправить строку 205
$cellIterator->setIterateOnlyExistingCells(false);
а так же исправить строку 206

foreach($row->getCellIterator() as $cell){
 
на 
 
foreach($cellIterator as $cell){


Опубликовано RoSk0 в ср, 25/08/2010 - 14:49.

кстати релиз на d.org будет?


Опубликовано reynholm в чт, 26/08/2010 - 14:06.

На d.org - нет, не будет. Ну не от меня, по крайней мере.
Во-первых не соблюдаются стандарты кодирования, во-вторых я с английским никак.


Опубликовано RoSk0 в сб, 28/08/2010 - 16:29.

теперь, если принять во внимание мои лополнения, то получается еще один нюанс - очистка о пустых строк перестает работать. И еще у меня почему то не работает импорт терминов таксономии.


Опубликовано reynholm в вс, 29/08/2010 - 09:02.

А на что ругается? Какие ошибки или как вообще выглядит "не работает"?


Опубликовано ihtiandr в вт, 07/09/2010 - 18:04.

Архиважный модуль. Спасибо. Мне без него просто никак :)
Вот только не могу победить 2 момента:
- при импорте ноде не назначается термин (хотя в словаре он появляется).
- не подцепляются cck-переменные.


Опубликовано reynholm в ср, 08/09/2010 - 06:38.

Интересно. Подробнее опишите, пожалуйста.


Опубликовано ihtiandr в ср, 08/09/2010 - 15:03.

Вот, вроде нащупал, почему CCK не подцепляется.
На свежеразвернутый Друпал в типе материала page (дефолтном) создал текстовое ССК поле. Все нормально, при импорте дает ее выбрать.
Если создать другой тип материала - связь с ССК теряется.

Дальше пока не продвигаюсь, ибо импорт "зацикливается":

rimport step 3

* warning: Invalid argument supplied for foreach() in Z:\home\n2\www\sites\all\modules\rimport\rimport.module on line 403.
* warning: Invalid argument supplied for foreach() in Z:\home\n2\www\sites\all\modules\rimport\rimport.module on line 508.

Добавление материалов, пожалуйста подождите...


Опубликовано reynholm в ср, 08/09/2010 - 15:36.

В этих строках модуль пытается читать массив строк из прайса.
И отсюда сразу вопросы:
- корректно ли загрузился сам xls файл?
- создался ли для него файл кеша (представляет из себя php файл с var_export()'ом массива строк/ячеек прайса)?
- подключился ли этот файл?

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


Опубликовано VasyOK в вт, 14/09/2010 - 17:41.

У меня тоже ошибки со строкой 187.

Можете ответить на вопрос: в режиме Обновление ваш модуль может удалять файлы фотографий из указанной директории?

А теперь не замечание, а пожелание:
обновление как я понял ведется по заголовку материала. Это хорошо если нет 2-х товаров с одинаковыми названиями, а если ваш модуль использовать не для товаров а для людей, в одном городе ведь может быть 2 человека с именем Иванов Иван Иванович. Идея пропатченого Node Import мне кажется лучше там можно указать обновление по ключевому полю.


Опубликовано reynholm в ср, 15/09/2010 - 10:16.

Да, в режиме обновление могут удаляться. Вот только связано это не с модулем, а с тем как выполняется node_save() для файловых полей. Судя по всему, даже если указано тоже имя файла, Друпал удаляет старый и только потом привязывает к ноде новый с тем же именем.

Про уникальность по имени я прекрасно понимаю. Список того что переделать/доделать достаточно большой лежит. Вот только сроков конкретных обещать не могу.


Опубликовано Arseniy в чт, 16/09/2010 - 05:04.

Может вопрос глупый, но этот модуль работает с уберкарт?


Опубликовано reynholm в чт, 16/09/2010 - 06:44.

Нет.


Опубликовано MGMaster в чт, 16/09/2010 - 09:52.

"reynholm" написал(а):

Нет.

А почему не работает?
Что мешает импортировать уберкартовские ноды?


Опубликовано reynholm в чт, 16/09/2010 - 10:10.

С полями CCK должен работать адекватно, с атрибутами не работает никак.


Опубликовано VasyOK в чт, 16/09/2010 - 14:41.

"reynholm" написал(а):

Да, в режиме обновление могут удаляться.

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

Ваш модуль стоит дописать. Может быть я и сам это сделаю, когда нормально выучу PHP в Drupal. Так что автор если будете отвечать на вопросы которые я пишу в разделе Программирование может и быстрее это проблема решится.


Опубликовано reynholm в чт, 16/09/2010 - 18:09.

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


Опубликовано MGMaster в пн, 01/11/2010 - 06:50.

Есть ли какие-нибудь продвижения?


Новое на сайте