spatie/simple-excel
Lightweight reader/writer for simple CSV and XLSX files in PHP/Laravel. Uses generators and LazyCollection for low memory usage on large files. Quickly stream rows for processing or export data without loading entire spreadsheets into memory.
Installation:
composer require spatie/simple-excel
No additional configuration is required—just start using it.
First Use Case: Read a CSV/Excel file and process its rows:
use Spatie\SimpleExcel\SimpleExcelReader;
SimpleExcelReader::create(public_path('file.xlsx'))
->getRows()
->each(function (array $row) {
// Process each row (e.g., save to DB, transform data)
\Log::info($row);
});
Where to Look First:
Reading Files:
SimpleExcelReader::create($filePath)
->getRowIterator()
->each(function (array $row) {
// Process row-by-row (ideal for large files)
});
$rows = SimpleExcelReader::create($filePath)->getCollection();
Writing Files:
use Spatie\SimpleExcel\SimpleExcelWriter;
SimpleExcelWriter::create(public_path('output.xlsx'))
->addRows([['col1', 'col2'], ['data1', 'data2']])
->save();
$writer = SimpleExcelWriter::create($filePath);
foreach ($largeDataset as $row) {
$writer->addRow($row);
}
$writer->save();
Integration with Laravel:
$file = request()->file('excel_file');
SimpleExcelReader::create($file->path())
->getRows()
->each(fn($row) => Model::create($row));
dispatch(new ProcessExcelJob($filePath));
class ProcessExcelJob implements ShouldQueue {
public function handle() {
SimpleExcelReader::create($this->filePath)->getRows()->each(...);
}
}
Validation & Transformation:
getRows() with map() or filter():
$validRows = SimpleExcelReader::create($filePath)
->getRows()
->filter(fn($row) => filled($row['required_field']));
Memory Usage:
getCollection() for files >10,000 rows. Use getRowIterator() or chunk processing:
SimpleExcelReader::create($filePath)
->getRows()
->chunk(1000)
->each(function ($chunk) {
Model::insert($chunk->toArray());
});
File Paths:
storage_path() or public_path() helpers.Excel-Specific Quirks:
PhpOffice\PhpSpreadsheet directly if formula evaluation is needed.CSV Delimiters:
SimpleExcelReader::create($filePath)->setCsvDelimiter(';');
->skipEmptyRows() to ignore blank rows.->setEncoding('UTF-8') for non-ASCII files.max_execution_time or process in chunks.Custom Row Processing:
Spatie\SimpleExcel\SimpleExcelReader or use decorators:
class CustomReader extends SimpleExcelReader {
public function getProcessedRows() {
return $this->getRows()->map(fn($row) => $this->transform($row));
}
}
Batch Processing:
Batch facade for DB inserts:
use Illuminate\Support\Facades\Batch;
Batch::group($rows, 500)
->then(function (Batch $batch) {
Model::insert($batch->items());
});
Testing:
SimpleExcelReader in tests:
$mockReader = Mockery::mock(SimpleExcelReader::class);
$mockReader->shouldReceive('getRows')->andReturn(collect([['test']]));
Performance:
cache():
$cachedRows = cache()->remember("excel_{$filePath}", now()->addHours(1), function() {
return SimpleExcelReader::create($filePath)->getCollection();
});
How can I help you explore Laravel packages today?