phpoffice/phpspreadsheet
PhpSpreadsheet is a pure PHP library to read and write spreadsheet formats like Excel and LibreOffice Calc. Create, edit, and export workbooks (XLSX, XLS, ODS, CSV, etc.) with a rich API for cells, formulas, styles, and more.
Installation:
composer require phpoffice/phpspreadsheet
Ensure your composer.json meets PHP 8.1+ requirements.
First Use Case: Load and read an Excel file:
use PhpOffice\PhpSpreadsheet\IOFactory;
$spreadsheet = IOFactory::load('path/to/file.xlsx');
$worksheet = $spreadsheet->getActiveSheet();
$cellValue = $worksheet->getCell('A1')->getValue();
Where to Look First:
src/PhpSpreadsheet/ (source code for advanced use cases).toArray() for Large Files:
Use iterators or cell-by-cell access to minimize memory:
foreach ($worksheet->getRowIterator() as $row) {
foreach ($row->getCellIterator() as $cell) {
$value = $cell->getValue();
}
}
$highestRow = $worksheet->getHighestRow();
$batchSize = 1000;
for ($row = 1; $row <= $highestRow; $row += $batchSize) {
$batch = $worksheet->rangeToArray(
'A' . $row,
'Z' . min($row + $batchSize - 1, $highestRow),
true,
false
);
// Process $batch
}
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
$worksheet = $spreadsheet->createSheet();
$worksheet->setTitle('Dynamic Data');
$worksheet->fromArray($dataArray, null, 'A1');
$style = $worksheet->getStyle('A1:A10');
$style->getFont()->setBold(true);
$style->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
$spreadsheet->setStrictReading(true); // Calculate all formulas
$value = $worksheet->getCell('B2')->getValue();
getFormattedValue() for human-readable dates:
$dateValue = $worksheet->getCell('C3')->getFormattedValue();
$file = request()->file('excel_file');
$spreadsheet = IOFactory::load($file->getPathname());
ProcessExcelJob::dispatch($spreadsheet, $userId)->onQueue('excel');
PhpSpreadsheet + Dompdf/mPDF:
$writer = IOFactory::createWriter($spreadsheet, 'Html');
$html = $writer->save('php://output');
$pdf = PDF::loadHTML($html)->setOption('isHtml5ParserEnabled', true);
return $pdf->stream('report.pdf');
Memory Overhead:
toArray() loads the entire worksheet into memory. For large files (>100K rows), use iterators or batch processing.getRowIterator() or rangeToArray() with limits.Empty Rows/Cells:
toArray() includes empty rows as null arrays. Filter manually:
$nonEmptyRows = array_filter($dataArray, fn($row) => !empty(array_filter($row)));
Merged Cells:
getMergeCells() to check:
if ($worksheet->getMergeCells()) {
$mergedCells = $worksheet->getMergeCells();
// Handle merged ranges
}
Formula Debugging:
$spreadsheet->setStrictReading(true);
Time Zones/Dates:
getDateTimeValue() for accurate parsing:
$date = $worksheet->getCell('D5')->getDateTimeValue();
$worksheet->getCell('A1')->setValue('=SUM(B1:C1)');
$worksheet->getCell('A1')->getCalculator()->setCreatePhpDoc(false); // Disable doc generation
getFormula() to inspect formulas before calculation:
$formula = $worksheet->getCell('B2')->getFormula();
setReadDataOnly(true) to skip metadata:
$reader = IOFactory::createReader('Xlsx');
$reader->setReadDataOnly(true);
$spreadsheet = $reader->load($file);
PhpOffice\PhpSpreadsheet\Writer\WriterInterface for new formats (e.g., CSV with headers).getValueBinder() to transform values on read/write:
$worksheet->getCell('A1')->setValueBinder(new class implements ValueBinder {
public function bindToCell(Cell $cell, $value) {
return strtoupper($value);
}
});
PhpOffice\PhpSpreadsheet\Event\BeforeSave to modify spreadsheets pre-save:
$spreadsheet->getEventDispatcher()->addListener(
'PhpOffice\PhpSpreadsheet\Event\BeforeSave',
function ($event) {
$event->getSpreadsheet()->getActiveSheet()->setTitle('Processed');
}
);
PhpSpreadsheet to the container for dependency injection:
$this->app->singleton(\PhpOffice\PhpSpreadsheet\Spreadsheet::class, function () {
return new \PhpOffice\PhpSpreadsheet\Spreadsheet();
});
$spreadsheet = Cache::remember("spreadsheet_{$fileHash}", now()->addHours(1), function () use ($file) {
return IOFactory::load($file);
});
[phpspreadsheet] for troubleshooting.How can I help you explore Laravel packages today?