Реалізація швидкого імпорту з Excel на PHP

    Ми продовжуємо розповідати про технології, що використовуються на нашому сервісі email-маркетингу Pechkin-mail.ru . Одним з ключових завдань будь-якого сервісу, пов'язаного з даними клієнтів, є завантаження цих даних на сервіс. Для Пєчкіна дуже важливо швидко і без проблем для користувача завантажувати адресні бази, що містять email-адреси, імена, прізвища та інші додаткові дані.
 
 

Що використати як інструмент?

В якості базового стандарту, використовуваного при імпорті адресних баз, ми взяли Microsoft Excel. Пояснюється це просто:
 
     
  • це стандартний інструмент, яким на базовому рівні володіють 100% користувачів комп'ютерів. Більш того, в бізнесі — це де-факто корпоративний стандарт і використовується навіть, якщо на робочих комп'ютерах Mac або Linux.
  •  
  • Практично всі CRM-, CMS-, хмарні або десктопні системи мають експорт в Excel або CSV, який простим пересохраненіем приводиться до формату XLS або XLSX.
  •  
  • Відомо також, що "90% помилок ПО сидить за півметра від монітора". Не в образу буде сказано рядовим користувачам, але ми повинні враховувати самий базовий рівень підготовки і тих. підтримки для пояснення досить сказати "Завантажте Excel-файл", а не пояснювати процедуру підготовки файлу в потрібному форматі.
  •  
 
Проблему користувачів при імпорті адресних баз зняли. Але тут виникає вже проблема безпосередньо розробки.
 
 
 

Наша біль, як розробників

 Excel — це не open-source розробка, а пропрієтарне рішення. Формат даних, особливо в нових версіях після 2007 року (xlsx), нетривіальний. На Пєчкіна використовується PHP, тому ми почали пошук бібліотек, які дозволять нам вирішити дану задачу. Але тут зіткнулися з проблемою, що цілий ряд бібліотек, не дозволяють читати xlsx:
 
     
  • php-spreadsheetreader reads a variety of formats (. xls,. ods AND. csv)
  •  
  • PHP-ExcelReader (xls only)
  •  
  • PHP_Excel_Reader (xls only)
  •  
  • PHP_Excel_Reader2 (xls only)
  •  
  • XLS File Reader Комерційна та xls only
  •  
  • SimpleXLSX З опису здатний читати xlsx, однак, автор посилається лише на xls
  •  
  • PHP Excel Explorer Комерційна та xls only
  •  
 
Звернула на себе нашу увагу бібліотека PHPExcel . Її ми використовували ще декілька років тому в сервісі sms-розсилок SMS24X7.ru . Петя Соколов (Petr_Sokolov ), наш талановитий розробник, написав обгортку для цієї бібліотеки, що виправляє ряд її недоліків і багів.
 
Бібліотека, безумовно, цікава і розвинена. Але для Пєчкіна її використовувати стало неможливо вже через пару років, коли виросли і ми і наші клієнти — її катастрофічна вимогливість до ресурсів і величезний час парсинга файлів. Наприклад, нерідкі випадки завантаження на сервіс адресних баз> 100 000 рядків зі складною структурою. А якщо файл вже 500000 рядків і "важить" більше 30Мб?
 
 

І тут нас відпустило…

У процесі пошуків ми наткнулися на комерційну бібліотеку libxl , побачивши результати "кустарного benchmark" на Stackoverflow.
 
Бібліотека написана на C + +, а завдяки чудовому об'єктно-орієнтованому розширенню для PHP від ​​Ilia Alshanetsky , легка в освоєнні і інтеграції (наприклад, переписати наше поточне рішення на PHPExcel на LibXL зайняло близько 3 годин). Що дуже класно, враховуючи, що, на жаль, документації від розробника розширення немає і необхідно користуватися розширенням Reflection.
 
Процес установки дуже простий.
 
 
cd /usr/local/src/

wget http://libxl.com/download/libxl.tar.gz
tar zxfv libxl.tar.gz

cd libxl-3.5.4.1/
ln -s include_c include
cd ../

wget https://github.com/iliaal/php_excel/archive/master.zip
unzip master.zip

cd php_excel-master/
./configure --with-excel --with-libxl-libdir=../libxl-3.5.4.1/lib64 --with-libxl-incdir=../libxl-3.5.4.1/include_c
make
make test
make install

 
У результаті компіляції ви отримаєте файл excel.so в папці / usr/lib/php5/20090626 /. Тепер досить створити файл / etc/php5/conf.d/excel.ini з вмістом.
 
extension=excel.so

 
Перевіримо встановився чи модуль і перезавантажити веб-сервер.
 
php -m | grep excel
service lighttpd restart

 
У коді все теж дуже просто. Довантажувати файл і читаєте необхідні комірки. Наприклад, ось так:
 
$doc = new ExcelBook(); 
$doc->loadFile(‘example.xls’);
for($r=$sheet->firstRow();$r<=$sheet->lastRow();$r++){
	for($c=$sheet-> firstCol();$c<=$sheet-> lastCol();$c++){
		echo ‘Строка: ’.$r.’ Столбец: ’.$c.’ Значение: ’.$sheet->read($r,$c).’<br />’;
	}
}

 
 

Отримані результати продуктивності

Відсутність потреби в оперативній пам'яті (в процесі завантаження файлу і його читання) приємно порадувало.
 
 
А ось і приріст швидкості завантаження excel-файлу і його читання на різних розмірах адресних баз.
 
 
Дані тести проводилися на xlsx-файлах з N передплатниками в один стоблец з email. Реальні ж адресні бази ще більше і складніше і перевагу в швидкості і споживанні пам'яті виглядає ще значніше.
 
Вартість бібліотеки 199 $ за девелоперську ліцензію, але, повірте, це того варто. Безумовно рекомендуємо всім, хто стикається з проблемою імпорту Excel-файлів на свій сервіс.
    
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.