box/spout
Fast, low-memory PHP library for reading and writing spreadsheet files (CSV, XLSX, ODS). Designed to handle very large files while using under ~3MB RAM. Requires PHP 7.2+, zip and xmlreader extensions. Archived/no longer maintained.
## Getting Started
### Minimal Setup
1. **Installation**
```bash
composer require box/spout
Spout is dependency-free and requires PHP 7.2+. Note: v3.3.0 introduces performance improvements for ODS/XLSX and fixes locale-dependent float handling.
First Use Case: Reading a CSV (Unchanged)
use Box\Spout\Reader\Common\Creator\ReaderEntityFactory;
use Box\Spout\Reader\CSV\Reader;
$reader = ReaderEntityFactory::createCSVReader();
$reader->open('path/to/file.csv');
foreach ($reader->getSheetIterator() as $sheet) {
foreach ($sheet->getRowIterator() as $row) {
$cells = $row->getCells();
// Process cells (e.g., $cells[0]->getValue())
}
}
$reader->close();
First Use Case: Writing an XLSX (Updated for v3.3.0)
use Box\Spout\Writer\Common\Creator\WriterEntityFactory;
use Box\Spout\Writer\XLSX\Writer;
$writer = WriterEntityFactory::createXLSXWriter();
$writer->openToFile('path/to/output.xlsx');
// v3.3.0: Supports strict OOXML and inline strings with multiple nodes
$writer->addSheet('Sheet1');
$writer->getSheet()->addRow(['Header1', 'Header2', 3.14159]); // Floats now locale-independent
$writer->getSheet()->addRow([1, 2]);
// Apply styling (performance improved in v3.3.0)
$writer->getSheet()->getStyleCell('A1')->applyFromArray([
'font' => ['bold' => true],
]);
$writer->close();
First Use Case: Reading/Writing ODS (New Performance Focus)
// ODS Reader (Performance improved in v3.3.0)
$reader = ReaderEntityFactory::createODSReader();
$reader->open('file.ods');
// ODS Writer (Performance improved in v3.3.0)
$writer = WriterEntityFactory::createODSWriter();
$writer->openToFile('output.ods');
src/Box/Spout/Reader/ and src/Box/Spout/Writer/ for core classes.tests/ for edge-case examples (e.g., large files, special characters).$reader = ReaderEntityFactory::createCSVReader();
$reader->open('users.csv');
foreach ($reader->getSheetIterator() as $sheet) {
foreach ($sheet->getRowIterator() as $row) {
$user = new User();
$user->name = $row->getCell(0)->getValue();
$user->email = $row->getCell(1)->getValue();
$user->save();
}
}
$reader->open('huge_file.xlsx'); // ODS/XLSX now faster
foreach ($reader->getSheetIterator() as $sheet) {
foreach ($sheet->getRowIterator() as $row) {
processRow($row); // Fire-and-forget or queue
}
}
$reader->open('data.csv');
$reader->setShouldSkipEmptyRows(false);
$reader->setFields([
'name' => 'col1',
'age' => 'col2',
]);
// Note: Headers now follow RFC6266 (v3.3.0)
$writer->openToBrowser('report.xlsx');
$writer->getSheet()->getStyleCell('A1')->applyFromArray([
'font' => ['bold' => true, 'size' => 14],
'alignment' => ['horizontal' => 'center'],
]);
// Example: Export users to XLSX in a command (v3.3.0 OOXML support)
public function handle() {
$writer = WriterEntityFactory::createXLSXWriter();
$writer->openToBrowser('users.xlsx');
$writer->addSheet('Users');
foreach (User::all() as $user) {
$writer->getSheet()->addRow([$user->name, $user->email, $user->created_at]);
}
$writer->close();
}
dispatch(new ExportUsersJob('users.xlsx')); // Leverage v3.3.0 ODS/XLSX performance
storage_path() for file paths.
$writer->openToFile(storage_path('app/exports/report.xlsx'));
$rowData = $row->getCells();
$validated = Validator::make($rowData, [
'email' => 'required|email',
]);
openToBrowser() for direct downloads without temp files.getRowIterator() with chunking:
$rows = iterator_to_array($sheet->getRowIterator(), false);
array_chunk($rows, 1000); // Process in chunks (ODS/XLSX now optimized)
$writer->setStrictOOXML(true); // New in v3.3.0
Box\Spout\Common\Entity\IO\Type to mock readers/writers in tests.Storage::fake() for testing file outputs.Memory Leaks (Unchanged)
$reader->close() or $writer->close() can leak resources.__destruct() or wrap in a try-finally block.
try {
$reader->open('file.csv');
// Process...
} finally {
$reader->close();
}
Encoding Issues (Unchanged)
$reader->setEncoding('UTF-8');
Large File Timeouts (Updated for v3.3.0)
setTimeout() or offload to a queue/CLI. Note: ODS/XLSX performance is now improved.setStrictOOXML(true) for better handling of edge cases.Sheet Limits (Unchanged)
Case Sensitivity (Unchanged)
setFields() are case-sensitive.How can I help you explore Laravel packages today?