coolsam/excel-import
A Laravel/PHP package for importing Excel files into your application. It offers a simple API for reading spreadsheets, mapping rows to models or arrays, and handling common import tasks with minimal configuration—useful for batch data loads and admin imports.
Architecture fit. This is a thin Filament plugin over maatwebsite/excel, not a standalone import engine. That is the correct shape for our context: Filament is our admin layer, spreadsheet I/O is commodity plumbing, and the wrapper keeps the underlying PhpSpreadsheet/laravel-excel engine reachable if we need to drop down. It fits the Eloquent-centric back-office pattern — upload, map headers, validate rows, persist to models, notify — and nothing else. It is not an ETL tool, not a data platform, and not a fit for multi-sheet reconciliation, cross-system joins, or scheduled external syncs. Those are separate problems and should not be scoped against this package.
Integration feasibility. Low-friction in the happy path: composer require, register the plugin in AdminPanelProvider, publish config, extend an importer class. The friction is in verification, not construction. The repo is named filament-excel-import, the description claims imports and exports, and the only release note (v1.2.0) mentions neither — just Laravel 12 compatibility. Before we size anything involving export, we clone and grep src/ for Export. Similarly the description advertises chunked reads, queued imports, and row-level validation; each needs to be confirmed in source rather than trusted from the README. The publish tag (excel-import-config) and the plugin FQCN also need source verification, because a wrong guess costs a half-day of confused debugging.
Technical risk. The dominant risk is maturity, not code quality. Zero stars, zero dependents, a 0.3 score, single maintainer, and no visible CI matrix or security policy. We should assume we are the first production user. The second risk is the breakage axis: v1.2.0 proves the maintainer tracks Laravel, but is silent on Filament, whose action/schema/form APIs move across majors and are the more likely cause of a routine composer update breaking us. Third is operational: PhpSpreadsheet's memory profile is disproportionate to file size, and the package's changelog says nothing about transactions, idempotency, or partial-write recovery on chunk failure. Fourth is the security surface — upload validation and formula-injection handling on any export path are effectively ours to own.
Key questions to resolve before committing.
filament/filament and maatwebsite/excel constraints in composer.json, and did the Laravel 12 bump force a laravel-excel major?Stack fit. We need three things in place before this package is worth anything: a working Filament panel, a queue driver (Redis/database/SQS), and a filesystem disk with a lifecycle policy for temporary uploads. On Laravel 12 the PHP floor is 8.2 regardless of the plugin — the "PHP 8.1+" claim is only relevant if we are still on Laravel 10/11. Without Filament, the correct move is maatwebsite/excel directly; adding Filament to justify this package would be a bad trade.
Migration path. This is additive, not a migration. There is no incumbent to displace; if we already use maatwebsite/excel elsewhere, both can coexist because this package is that engine underneath. The real migration path is exit: because the plugin is thin, replacement cost is "swap the Filament action for our own and keep laravel-excel" — a day or two, not a quarter. That reversibility is the main reason this is a low-commitment bet.
Compatibility posture. Pin ^1.2 on Laravel 12 (earlier versions do not declare compatibility). Pin exact versions of coolsam/excel-import, filament/filament, and maatwebsite/excel. Put a constraint audit in CI so a routine composer update surfaces a Filament or laravel-excel major bump as a deliberate decision rather than a production incident.
Sequencing.
tree src/, grep for Export, read composer.json constraints. Half a day. Do this before any estimate is socialized.SpreadsheetImport contract and implement it once with this package. No Coolsam\ExcelImport\* types in domain code. Every exit path then costs one file, not a hundred call sites.updateOrCreate on a natural key so retries after partial failure are safe.DB::transaction() where volume allows, temp-disk pruning on a schedule or in the job's finally, failure-row export rather than logging, notifications on both success and failure.Ramp-up. Low for a Laravel developer — a day to first working import, and the wrapper seam keeps the learning contained. The conventions that need to be taught are the seam rule, the one-importer-per-model rule, and the header-normalization step (UTF-8 BOM stripping, whitespace/case normalization, explicit date parsing, preserving leading zeros and phone-number formatting that Excel destroys).
Maintenance. Single maintainer, zero dependents, zero stars — the operational assumption is that upstream will not notice our bugs. We should be prepared to vendor-patch or fork rather than wait. The maintenance burden we take on is not the plugin code; it is the surrounding ownership: upload security validation, formula-injection rejection on any export, temp-file lifecycle, and idempotency design. Budget for those explicitly — they are not free features of the package.
Support. No evidence of a security policy or disclosure process. Treat upload handling as code we own because we do. Escalation path is upstream issue → fork. That is acceptable for internal operator tooling and unacceptable for anything gating a revenue path or touching regulated data.
Scaling. PhpSpreadsheet is the constraint, not the file size — a 10MB XLSX is not a 10MB memory cost. Levers in order of effect: reduce chunk size, cap queue:work --memory, raise the worker's PHP memory_limit, and never run imports inside the web request. Verify with a deliberately oversized fixture that the chunked path is actually the one executing; a package can expose chunking and still default to a synchronous full-sheet read. For concurrency, decide up front whether two operators can import the same resource simultaneously, and if not, lock it — natural-key upserts make collisions survivable but not free.
Failure modes to design for now.
failed_jobs first.finally.d/m/Y vs m/d/Y), scientific-notation IDs, dropped leading zeros. Normalize to a canonical map before the importer sees a row.=, +, -, @ prefixes.Observability. Queued imports are invisible by default. Notifications with row counts and a link to a failed-row report convert "the import is broken" into "3 rows failed validation, here's why." Log the row number and raw row array on every validation failure — without it, debugging is guesswork.
Testing. Keep tiny fixtures (3–5 rows) covering four cases: happy path, bad header, duplicate key, validation failure. Those catch most regressions when the package or Filament updates. Storage::fake() and Queue::fake() make the Filament action testable without a worker. Run QUEUE_CONNECTION=sync in dev so the import loop is debuggable with a normal stack trace.
Decision recommendation. Adopt behind an evaluation gate, not as a standard. The strategic cost is near zero — thin adapter, days to replace, and v1.2.0 keeps it off the critical path of a Laravel 12 upgrade. The value is real: it converts recurring bulk-upload asks from multi-week builds into sprint-scale deliverables. The gate is the one-day spike plus surface verification. If the spike succeeds, promote it to standard for internal operator-facing imports and revisit export scope separately. If it fights us, we have lost a day and still hold maatwebsite/excel.
How can I help you explore Laravel packages today?