akeneo-labs/spreadsheet-parser
Lightweight spreadsheet reader focused on low memory usage, even for large files. Parses XLSX and CSV, exposes workbook/worksheet APIs, and provides row iterators for streaming data extraction with configurable CSV options (encoding, delimiter, enclosure, etc.).
Installation
composer require akeneo-labs/spreadsheet-parser
Add to composer.json if using a monorepo or legacy setup:
"repositories": [
{ "type": "vcs", "url": "https://github.com/akeneo-labs/spreadsheet-parser" }
]
First Use Case: Parsing a Simple XLSX
use Akeneo\Tool\Bundle\SpreadsheetBundle\Parser\Parser;
$parser = new Parser();
$filePath = storage_path('app/uploads/example.xlsx');
$result = $parser->parse($filePath);
// Access parsed data (returns an associative array)
foreach ($result as $row) {
dd($row); // Debug first row
}
Key Files to Reference
src/Akeneo/Tool/Bundle/SpreadsheetBundle/Parser/Parser.php (Core class)tests/ (Unit/integration tests for edge cases)Resources/config/services.yml (Service container config if using Symfony)Service Provider Binding
// app/Providers/AppServiceProvider.php
public function register()
{
$this->app->bind(Parser::class, function ($app) {
return new Parser();
});
}
Controller Usage
use Akeneo\Tool\Bundle\SpreadsheetBundle\Parser\Parser;
public function uploadExcel(Request $request)
{
$request->validate(['file' => 'required|file|mimes:xlsx']);
$parser = app(Parser::class);
$data = $parser->parse($request->file('file')->getRealPath());
// Process $data (e.g., save to DB)
return response()->json(['success' => true]);
}
Chunked Processing for Large Files
$parser = new Parser();
$parser->setChunkSize(1000); // Process 1000 rows at a time
$data = $parser->parse($filePath);
foreach ($data as $chunk) {
Model::insert($chunk); // Batch insert
}
$parser->setHeaderRow(1); // Skip first row (assume row 0 is headers)
$mappedData = [];
foreach ($result as $row) {
$mappedData[] = [
'id' => $row['ID'],
'name' => $row['Product Name'],
];
}
if (!$parser->isValid($filePath)) {
throw new \Exception('Invalid Excel file');
}
Memory Limits
memory_limit. Use setChunkSize() or process in streams.memory_limit in php.ini or use ini_set('memory_limit', '256M') in code.Encoding Issues
é, ü) may corrupt. Use mb_convert_encoding():
$row = mb_convert_encoding($row, 'UTF-8', 'auto');
Date/Time Parsing
PhpOffice\PhpSpreadsheet for conversion if needed:
$date = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row['Date']);
Symfony Dependency
LoggerInterface:
$parser = new Parser(new NullLogger());
\Log::debug('Parsed row', ['data' => $row]);
if (empty($result) || !isset($result[0]['ExpectedColumn'])) {
throw new \RuntimeException('Malformed Excel structure');
}
Custom Parsing Logic
Override Parser::parse() or extend the class:
class CustomParser extends Parser {
protected function transformRow($row) {
return [
'slug' => Str::slug($row['name']),
'price' => (float) $row['price'],
];
}
}
Event Listeners Use Laravel’s events to hook into parsing:
event(new SpreadsheetParsed($data));
Queue Jobs for Heavy Processing
dispatch(new ProcessExcelJob($filePath, $data));
How can I help you explore Laravel packages today?