phpoffice/phpspreadsheet
PhpSpreadsheet is a pure-PHP library to read and write spreadsheet files (Excel, LibreOffice Calc, and more). Create, modify, and export workbooks with rich formatting, formulas, and multiple formats via a well-documented API.
Installation:
composer require phpoffice/phpspreadsheet
Requires PHP 8.1+ and PHP Zip extension (for .xlsx/.ods support).
First Use Case:
Generate a simple .xlsx file with sample data:
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setCellValue('A1', 'Hello, PhpSpreadsheet!');
$writer = new Xlsx($spreadsheet);
$writer->save('hello.xlsx');
Key Entry Points:
Spreadsheet: Root object (creates new files).Writer\*: Handles file output (e.g., Xlsx, Csv).Reader\*: Handles file input (e.g., Xlsx, Csv).Where to Look First:
examples/ directory in the repo for practical examples.use PhpOffice\PhpSpreadsheet\IOFactory;
$spreadsheet = IOFactory::load('input.xlsx');
$sheetData = $spreadsheet->getActiveSheet()->toArray();
foreach ($spreadsheet->getActiveSheet()->getRowIterator() as $row) {
$cellIterator = $row->getCellIterator();
$cellIterator->setIterateOnlyExistingCells(false); // Include empty cells
foreach ($cellIterator as $cell) {
echo $cell->getValue();
}
}
$data = [
['Name', 'Age'],
['John', 30],
['Jane', 25]
];
$sheet->fromArray($data, null, 'A1'); // null = default style, A1 = top-left cell
$sheet->fromArray(
['Product', 'Price'],
null,
'A1',
false, // Don't overwrite existing data
false // Don't add new rows
);
$sheet->getStyle('A1:A10')
->getConditionalFormatting()
->createConditionalFormat('greaterThan')
->setFormula(['value' => 50])
->getFill()
->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
->getStartColor()
->setARGB('FFFF0000'); // Red
$style = $sheet->getStyle('A1');
$sheet->getStyle('B1')->applyFromArray($style->getConditionalFormatting());
$sheet->setCellValue('A1', '=SUM(B1:B10)');
$sheet->setCellValue('B1', 10);
$sheet->setCellValue('B2', 20);
// ... update B1-B10, formula auto-adjusts
$sheet->getNamedRange('SalesData')->setRefersTo('Sheet1!$B$1:$B$100');
$sheet->mergeCells('A1:D1');
$sheet->setCellValue('A1', 'Merged Header');
$sheet->getProtection()->setSheet(true);
$sheet->getProtection()->setPassword('secret');
Storage facade to save files to disk:
use Illuminate\Support\Facades\Storage;
Storage::disk('public')->put('reports/report.xlsx', $writer->saveToString());
dispatch(new GenerateReportJob($data, $filename));
Memory Management:
Allowed memory exhausted errors.setMemoryCacheSize() to limit cache size:
$spreadsheet->getMemoryCacheSize() > 0 ? $spreadsheet->getMemoryCacheSize() : 1024; // 1MB
.xlsx/ods:
$writer->setUseMemoryCache(false);
$writer->save('large_file.xlsx');
Formula References:
copyformula() may fail if source cell is deleted.$A$1) or validate cells exist first.Cell Caching:
$cell = $sheet->getCell('A1');) break if the sheet is modified later.$cell = $sheet->getCell('A1'); // Re-fetch
Time Zones/Dates:
$sheet->getStyle('A1')->getNumberFormat()->setFormatCode('yyyy-mm-dd');
CSV Delimiters:
; or \t as delimiters, breaking parsing.$reader = new \PhpOffice\PhpSpreadsheet\Reader\Csv();
$reader->setDelimiter(';');
Large File Handling:
.xlsx files >20MB may time out or fail to upload.$writer->setCompression(\PhpOffice\PhpSpreadsheet\Writer\Xlsx::COMPRESSION_MAX);
getCell('A1')->getCalculatedValue() to debug formula results.$spreadsheet->getActiveSheet()->getCell('A1')->getFormula();
$sheet->getStyle('A1')->applyFromArray(['font' => ['bold' => true]]);
memory_get_usage() and microtime() to identify bottlenecks.Writer\AbstractWriter to support new formats (e.g., .xlsb).PhpOffice\PhpSpreadsheet\Cell\ValueBinderInterface for custom data types (e.g., UUIDs).PhpOffice\PhpSpreadsheet\Event\BeforeSave to modify files pre-save:
$spreadsheet->getEventDispatcher()->addListener(
\PhpOffice\PhpSpreadsheet\Event\BeforeSave::class,
function ($event) {
$event->getSpreadsheet()->getActiveSheet()->setTitle('Modified');
}
);
Reader\AbstractReader.$spreadsheet->getDefaultStyle()->getFont()->setName('Arial');
$sheet->getStyle('A1:C10')->getAutoFilter()->setAutoFilter(true);
$sheet->getCell('A1')->getHyperlink()->setUrl('https://example.com');
How can I help you explore Laravel packages today?