PHP-инструменты для работы с электронными таблицами XLSX
Обзор библиотек для работы с XLSX в PHP
Как эффективно читать и писать XLSX-файлы на PHP?
PhpSpreadsheet
Наиболее функциональная библиотека, наследница PHPExcel. Поддерживает чтение, запись, стили, формулы, диаграммы. Установка через Composer:
composer require phpoffice/phpspreadsheetPhp xlsx файл (работа с xlsx-файлами в php)
Пример чтения:
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
$spreadsheet = $reader->load('example.xlsx');
$sheet = $spreadsheet->getActiveSheet();
foreach ($sheet->getRowIterator() as $row) {
foreach ($row->getCellIterator() as $cell) {
echo $cell->getValue() . "\t";
}
echo "\n";
}
Пример записи:
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setCellValue('A1', 'Hello');
$sheet->setCellValue('B1', 'World');
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->save('output.xlsx');
Типичные проблемы и их решения:
- Ошибка "Allowed memory size exhausted" при загрузке большого файла. Используйте ReadFilter для загрузки только нужных строк.
- Неверное отображение дат - даты хранятся как числа. Для преобразования используйте
PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($value). - Проблемы с кодировкой - файл может быть в windows-1251. Тогда укажите кодировку при записи или конвертируйте данные.
Как прочитать XLSX-файл без лишних зависимостей?
SimpleXLSX
Легковесная библиотека для чтения XLSX. Не поддерживает запись. Установка:
composer require shuchkin/simplexlsx
Пример:
if ($xlsx = SimpleXLSX::parse('file.xlsx')) {
$rows = $xlsx->rows();
print_r($rows);
}
Минусы: нет поддержки стилей, формул, даты могут требовать дополнительной обработки. Подходит для простого импорта данных.
Ошибка: Call to undefined method - проверьте, что autoload подключен. Также файл может быть повреждён - SimpleXLSX вернёт false.
Как быстро записать большой объём данных в XLSX?
OpenSpout
Библиотека для быстрой записи больших наборов данных. Минимальное потребление памяти. Установка:
composer require openspout/openspout
Пример записи 10000 строк:
use OpenSpout\Writer\XLSX\Writer;
$writer = new Writer();
$writer->openToFile('large.xlsx');
for ($i = 0; $i < 10000; $i++) {
$writer->addRow(new \OpenSpout\Common\Entity\Row([$i, "row $i"]));
}
$writer->close();
OpenSpout не поддерживает чтение и стили. Подходит для экспорта данных.
Проблема: при попытке открыть файл после записи может быть сообщение о повреждении - проверьте, что writer корректно закрыт. Также убедитесь, что расширение zip доступно.
Расширенный пример чтения с фильтрацией строк и колонок
Использование ChunkReadFilter для экономии памяти:
class ChunkReadFilter implements \PhpOffice\PhpSpreadsheet\Reader\IReadFilter {
private $startRow;
private $endRow;
public function __construct($startRow, $endRow) {
$this->startRow = $startRow;
$this->endRow = $endRow;
}
public function readCell($column, $row, $worksheetName = '') {
if ($row >= $this->startRow && $row <= $this->endRow) {
return true;
}
return false;
}
}
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
$reader->setReadFilter(new ChunkReadFilter(1, 100));
$spreadsheet = $reader->load('bigfile.xlsx');
$sheet = $spreadsheet->getActiveSheet();
$data = $sheet->toArray();
print_r($data);
Array ( [0] => Array ( [0] => Header1 [1] => Header2 ) ... )
Создание файла с форматированием и объединением ячеек
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$styleArray = [
'font' => ['bold' => false, 'color' => ['argb' => 'FF0000']],
'fill' => ['fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID, 'startColor' => ['argb' => 'FFFF00']],
];
$sheet->getStyle('A1:C1')->applyFromArray($styleArray);
$sheet->setCellValue('A1', 'Заголовок');
$sheet->mergeCells('A1:C1');
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->save('styled.xlsx');
echo "Файл styled.xlsx создан";
Работа с формулами и вычислениями
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setCellValue('A1', 10);
$sheet->setCellValue('B1', 20);
$sheet->setCellValue('C1', '=A1+B1');
$spreadsheet->getCalculationEngine()->getInstance()->calculate($spreadsheet);
$result = $sheet->getCell('C1')->getCalculatedValue();
echo "Результат: $result"; // 30
Результат: 30
Запись больших данных с помощью OpenSpout и прогресс-бар (демонстрация)
use OpenSpout\Writer\XLSX\Writer;
use OpenSpout\Common\Entity\Row;
$writer = new Writer();
$writer->openToFile('large_export.xlsx');
$header = ['ID', 'Name', 'Email'];
$writer->addRow(Row::fromValues($header));
for ($i = 1; $i <= 100000; $i++) {
$row = Row::fromValues([$i, "User $i", "user$i@example.com"]);
$writer->addRow($row);
if ($i % 10000 == 0) {
echo "Записано $i строк\n";
}
}
$writer->close();
echo "Готово";
Записано 10000 строк ... Готово