Экспорт из PHP в Excel с помощью PhpSpreadsheet

В своей профессиональной деятельности я периодически сталкиваюсь с задачами экспорта/генерации данных в формате XLS/XLSX (Excel). Библиотека PhpSpreadsheet позволяет их решить.

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

Скачать и установить библиотеку предлагается с помощью composer:

composer require phpoffice/phpspreadsheet

Сайт: https://phpspreadsheet.readthedocs.io

Опишу реализацию типичных задач.

Обратите внимание, что для корректной работы XMLWriter (библиотеки PHP) необходима корректная его настройка:

Типовой Hello World

<?php
require 'vendor/autoload.php';

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;

$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setCellValue('A1', 'Hello World !');

$writer = new Xlsx($spreadsheet);
$writer->save('hello world.xlsx');

Получение Excel документа через Ajax запрос

Php обработчик генерации XLSX документа:

header('Content-Type: application/json');

require 'vendor/autoload.php';

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;

$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();

//some code...

$writer = new Xlsx($spreadsheet);
ob_start();
$writer->save('php://output');
$xlsData = ob_get_contents();
ob_end_clean();
echo json_encode('data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,'.base64_encode($xlsData));

JS:

$.ajax({
    type:'POST',
    url:"...", // path to php handler
    data: {...}, // some post data
    dataType:'json'
}).done(function(data){
    var $a = $("<a>");
    $a.attr("href",data);
    $("body").append($a);
    $a.attr("download","Report.xlsx");
    $a[0].click();
    $a.remove();
});

Здесь кратко поясню:

PHP обработчик формирует Excel документ и кодирует его в base64. Далее JS создает временную ссылку и в тег «href» кладёт этот закодированный контент. После инициации клика по ссылке происходит скачивание XLSX документа, а сама ссылка удаляется со страницы. Этакая мгновенная генерация Excel документа.

Установка заголовка листа

$sheet = $spreadsheet->getActiveSheet();
$sheet->setTitle('Some title');

Добавление текстового контента в ячейку

Можно добавлять по координатам (отчет начинается с единицы):

$sheet = $spreadsheet->getActiveSheet();
//$columnIndex - номер колонки
//$row - номер строки
//$data - текстовые данные для добавления
$sheet->setCellValueByColumnAndRow($columnIndex, $row, $data);

Также можно воспользоваться символьными идентификаторами:

$sheet = $spreadsheet->getActiveSheet();
$sheet->setCellValue('A1', 'Some data');

Выравнивание

По координатам:

$sheet->getStyleByColumnAndRow(1,1)
->getAlignment()
->setHorizontal(PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_RIGHT);

Через идентификатор ячейки:

$sheet->getStyle('B1')
      ->getAlignment()
      ->setHorizontal(PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_RIGHT);

Через интервал идентификаторов ячеек:

$sheet->getStyle('B1:B5')
      ->getAlignment()
      ->setHorizontal(PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_RIGHT);

Установка стиля границы (border) ячейки/ячеек

$borderStyleArray = array(
    'borders' => array(
        'outline' => array(
            'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
            'color' => array('rgb' => '000000'),
        ),
        'horizontal' => array(
            'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
            'color' => array('rgb' => '000000'),
        ),
        'vertical' => array(
            'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
            'color' => array('rgb' => '000000'),
        ),
    ),
);
$sheet->getStyle('F4:J4')->applyFromArray($borderStyleArray);

Объединение ячеек

$sheet->mergeCells('A4:E4');

Заливка ячейки/ячеек цветом

$sheet->getStyle('F4')
      ->getFill()
      ->setFillType(PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)  
      ->getStartColor()
      ->setRGB('ecf9fd');

p.s. более подробную документацию по PhpSpreadsheet можно найти в самой библиотеке, скачанной с помощью composer-а: