Наверняка многие думают, что Excel формата XLSX очень сложен для чтения и нужно обязательно использовать сложные скрипты и библиотеки. Так было со старым форматом XLS. Для нового экселя – все куда проще. XLSX – это зип архив, внутри которого в виде XML расположены данные по ячейкам и все остальные – в стандартной структуре с малыми хитростями.
Знания этого можно применять для настройки импорта данных из экселя. Любых данных. В дальнейшем мы разберем, как можно самостоятельно создавать эксель файл, не прибегая к супер библиотекам.
Нам понадобятся PHP 5, встроенный модуль ZIP и SimpleXML. Как вы думаете, сколько строк кода нам понадобится?
Для примера - расположим файл в папке со скриптом. Назовем его file.xlsx. Из данного файла нам понадобятся файл с данными по первому листу. Он расположен по адресу
file.xlsx/xl/worksheets/sheet1.xml
И файл с частыми строками, сделанный из соображений экономии повторяющихся фраз
file.xlsx/xl/sharedStrings.xml
Нужно считать все строки и вставлять их значения при нахождении ссылки на строку
Сказано – сделано. Создаем ассоциативный массив
$file=file_get_contents('zip://file.xlsx#xl/sharedStrings.xml');
$xml=(array)simplexml_load_string($file);
$sst=array();
foreach ($xml['si'] as $item=>$val)$sst[]=iconv('UTF-8','windows-1251',(string)$val->t);
Первой строкой – мы считываем полный текст распакованного файла внутри архива
Далее – собираем XML структуру в ассоциативный массив
После чего – пробегаемся по элементам массива, записывая значения в итоговый массив $sst. ICONV используется только в случае, если у вас кодировка – не UTF-8
Что дальше? Дальше чуть сложнее. Двумерный массив с возможными ассоциациями
$file=file_get_contents('zip://file.xlsx#xl/worksheets/sheet1.xml');
$xml=simplexml_load_string($file);
$data=array();
foreach ($xml->sheetData->row as $row){
$currow=array();
foreach ($row->c as $c){
$value=(string)$c->v;
$attrs=$c->attributes();
if ($attrs['t']=='s'){
$currow[]=$sst[$value];
}else{
$currow[]=$value;
}
}
$data[]=$currow;
}
Собираем первый лист. Формируем XML, после чего проходимся по каждой строке row и разбираем каждю ячейку. Для получения атрибутов ячейки – используем свойство attributes(). Если атрибут ‘t’==’s’ – значит значение ячейки – это строка в ассоциативном массиве, полученном ранее.
После сбора строки в массив – соединяем в наш общий массив $data. На самом деле – вместо этого можно было бы сразу добавлять в таблицу, или использовать дополнительные проверки.
Все. Дело сделано. Первый лист прочитан и собран в массив. Сколько строк получилось? 20. Можно было бы сжать сильнее, оптимизировать. Если интересна структура файла – берите архиватор ZIP и смело пытайте XLSX. У вас обязательно получится
Гость
Переменная $sst ничего не делает
Гость
А как насчет пустых ячеек ?
Где они ?
Гость
Автор, большое спасибо!
Но лучше куски кода было соединить в один - я вот спустя 3 часа понял, что они взаимозависимы ;)
Гость
Warning: file_get_contents(zip://file.xlsx#xl/worksheets/sheet1.xml): failed to open stream: operation failed
Гость
Вероятно у вас отключено zip extension, необходимый для работы скрипта
Гость
Класс! Спасибо автору за точность и краткость.