Йо! Часто нам нужно выгрузить что-то в excel. Например каталог с картинками и его свойствами. Это вполне тривиальная задача, но я помню, что меня пугала работа с картинками и изучение библиотеки PhpSpreadsheet. Однажды мне пришлось этим заняться, когда пришёл заказ на создание его выгрузки из Bitirix’а (конечно пришлось поработать ещё и с кодировкой для правильной работы). По результатам работы я написал статью. А сегодня расскажу как создать и выгрузить таблицу с картинками в PHP c помощью PhpSpreadsheet.
Подключаемся по ssh к нашему серверу и устанавливаем композер в папку с проектом:
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" php -r "if (hash_file('sha384', 'composer-setup.php') === '8a6138e2a05a8c28539c9f0fb361159823655d7ad2deecb371b04a83966c61223adc522b0189079e3e9e277cd72b8897') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" php composer-setup.php php -r "unlink('composer-setup.php');"
Далее ставим PhpSpreadsheet:
composer require phpoffice/phpspreadsheet
Установили!)
Создаём файл __ВАШЕ__НАЗВАНИЕ__.php в удобном месте и заходим в него. Там подключаем библиотеку и нужные юзам namespases:
<?php require '__ПУТЬ_ДО_ПАПКИ_С_БИБЛИОТЕКОЙ__/vendor/autoload.php'; use PhpOffice\PhpSpreadsheet\Spreadsheet; // Работа со структурой документа use PhpOffice\PhpSpreadsheet\Writer\Xlsx; // Запись в нужный формат. Если мы говорим только об excel то там может быть ещё Xls use PhpOffice\PhpSpreadsheet\Worksheet\Drawing; // Встроенные методы для работы с картинками.
И так… мы подключили. Теперь нам нужно создать новый экземпляр «документа», выбрать текущую вкладку и добавить в неё заголовки:
$spreadsheet = new Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); // Структура документа $sheet->setCellValue('A1', 'Картинка'); $sheet->setCellValue('B1', 'Название'); $sheet->setCellValue('C1', 'Количество'); $sheet->setCellValue('D1', 'Остаток'); $sheet->setCellValue('E1', 'Цена'); $sheet->setCellValue('F1', 'Сумма'); $sheet->setCellValue('G1', 'Код');
Вы наверное уже поняли какая будет таблица и структура массива, из которого мы будем её строить. Но на всякий случай я покажу вам тот самый массив:
$data = [ [ img=> './images/1.png', // Адрес картинки на вашем сервере name=> 'Текс', // Имя count => 'sd', // Количество ost=>'5', // Остаток товара price=> '2', // Цена summ=>'sd', // Сумма code=>'2' // Код товара ] ...... ];
Соответственно нам нужно дальше идти по массиву и вставлять данные нужные ячейки.
$i = 2; // Начинаем с двойки, нумерациия в таблице идёт с 1-цы foreach($data as $row){ // Получаем данные ячеек $img = $row['img']; $name = $row['name']; $count = $row['count']; $ost = $row['ost']; $price = $row['price']; $summ = $row['summ']; $code = $row['code']; // Img if(!empty($img)){ $drawing = new Drawing(); // Новый экземпляр "Рисоваки") $drawing->setName($name); // Имя картинки $drawing->setDescription($name); // Описание $drawing->setPath($img); // Абсолютный путь на сервере к картинке $drawing->setCoordinates('A'. $i); // Координаты картинки $drawing->getShadow()->setVisible(true); // Тень если нужно $drawing->setWorksheet($sheet); // Нужная вкладка $drawing->setHeight(100); // Высота в пикселях $drawing->setWidth(100); // Ширина в пикселях } // Another data $sheet->setCellValue('B' . $i, $name); // Конкатинируем с $i и получаем нужную ячейку $sheet->setCellValue('C' . $i, $count); $sheet->setCellValue('D' . $i, $ost); $sheet->setCellValue('E' . $i, $price); $sheet->setCellValue('F' . $i, $summ); $sheet->setCellValue('G' . $i, $code); // Set row height $spreadsheet->getActiveSheet()->getRowDimension($i)->setRowHeight(100); // Выставляем высоту всей строки как у картинки $i++; }
Далее нужно сделать преобразование колонкой «A» — выставить ширину по всей вкладке. И тут проблема! Ширина выставляется в единицах измерения excel’ так, что подберите свою, но кажется, что соотношение с пикселями примерно 1/5
$spreadsheet->getActiveSheet()->getColumnDimension('A')->setWidth(20);
При значении ширины колонки 20, а ширина картинки 100 получиться примерно так:
После того как мы получили все данные, осталось записать на сервер нашу excel’ку)
$writer = new Xlsx($spreadsheet); $writer->save(_АБСОЛЮТНЫЙ_ПУТЬ_НА_СЕРВЕРЕ_ . _ИМЯ_ .xlsx');
Ещё было бы не плохо отдавать ссылку на файл, чтобы скачивать с сайта.
echo '<a target="_blank" href="__ДОМЕН__ . _ПУТЬ_ДО_ФАЙЛА">Скачать</a>';
В моём случае нужна была переиспользуемая функция и я обернул коды так:
<?php require 'vendor/autoload.php'; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Writer\Xlsx; use PhpOffice\PhpSpreadsheet\Worksheet\Drawing; function createnGetLinkExcel($id, $data){ $spreadsheet = new Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); $sheet->setCellValue('A1', 'Картинка'); $sheet->setCellValue('B1', 'Название'); $sheet->setCellValue('C1', 'Количество'); $sheet->setCellValue('D1', 'Останок'); $sheet->setCellValue('E1', 'Цена'); $sheet->setCellValue('F1', 'Сумма'); $sheet->setCellValue('G1', 'Код'); $i = 2; foreach($data as $row){ $img = $row['img']; $name = $row['name']; $count = $row['count']; $ost = $row['ost']; $price = $row['price']; $summ = $row['summ']; $code = $row['code']; // Img if(!empty($img)){ $drawing = new Drawing(); $drawing->setName($name); $drawing->setDescription($name); $drawing->setPath($img); // put your path and image here $drawing->setCoordinates('A'. $i); $drawing->getShadow()->setVisible(true); $drawing->setWorksheet($sheet); $drawing->setHeight(100); $drawing->setWidth(100); } // Another data $sheet->setCellValue('B' . $i, $name); $sheet->setCellValue('C' . $i, $count); $sheet->setCellValue('D' . $i, $ost); $sheet->setCellValue('E' . $i, $price); $sheet->setCellValue('F' . $i, $summ); $sheet->setCellValue('G' . $i, $code); // Set row height $spreadsheet->getActiveSheet()->getRowDimension($i)->setRowHeight(100); $i++; } $spreadsheet->getActiveSheet()->getColumnDimension('A')->setWidth(20); $writer = new Xlsx($spreadsheet); $writer->save('result/order_'. $id .'.xlsx'); echo '<a target="_blank" href="result/order_'. $id .'.xlsx">Скачать</a>'; } // Тестовые данные $data = [ [ img=> 'images/1.png', name=> 'Текс', count => 'sd', ost=>'5', price=> '2', summ=>'sd', code=>'2' ] ]; // Пример вызова createnGetLinkExcel('15', $data);