Fast Excel 5.x: Streaming Imports and Safer Exports
Fast Excel has grown well beyond its v2.2 roots of simple collection exports and browser downloads. The 5.x release series adds lazy streaming imports, fine-grained chunked import controls, sheet and column selection, and a built-in guard against formula injection — making it a practical choice for large operational data pipelines, not just quick report downloads.
The package continues to use OpenSpout under the hood, keeping memory usage low by avoiding a full in-memory parse of every spreadsheet.
Lazy Imports for Large Files
The original import() method loads every row into a collection at once. For large uploads that can exhaust available PHP memory. importLazy(), introduced in Fast Excel 5.12, yields rows through a LazyCollection so you can process them in batches without holding the entire file in memory:
use App\Models\Contact;
use Illuminate\Support\LazyCollection;
use Rap2hpoutre\FastExcel\FastExcel;
(new FastExcel)->importLazy('contacts.xlsx')
->chunk(1_000)
->each(function (LazyCollection $contacts) {
Contact::insert($contacts->all());
});
This pattern is a clean alternative to manual CSV parsing for large file uploads.
Chunked Imports with Stable Headings
When you need a queued job to process only a slice of a spreadsheet, three methods give you precise control:
headerRow(int $row)— reads column keys from the specified heading rowstartRow(int $row)— sets where the current chunk beginslimitRows(int $count)— caps the number of rows read
use Rap2hpoutre\FastExcel\FastExcel;
$rows = (new FastExcel)
->headerRow(1)
->startRow(2 + ($page * 1_000))
->limitRows(1_000)
->import('orders.xlsx');
Before Fast Excel 5.17, startRow() also treated the selected row as the heading row, so a later chunk could accidentally use a data row as its keys. headerRow() (added in #418) separates those two concerns without breaking the existing startRow() behaviour.
Selecting Sheets and Columns
Fast Excel 5.16 added sheet() and onlyColumns() to limit exactly what data an import reads:
use Rap2hpoutre\FastExcel\FastExcel;
$orders = (new FastExcel)
->sheet('Orders')
->onlyColumns(['A', 'B', 'H'])
->import('customer-export.xlsx');
onlyColumns() accepts column letters or one-based integer positions. It prevents empty fields from appearing when spreadsheet formatting extends far beyond the real data. limitColumns() is also available when you need every column up to a given position.
Escaping Spreadsheet Formulas
Values that begin with =, +, -, or @ are interpreted as formulas by most spreadsheet applications. When those values originate from user-controlled input — an uploaded CSV or a database field — an export can inadvertently execute arbitrary formulas when someone opens the file.
Fast Excel 5.17 added escapeFormulas() (#411) to write such values as plain text:
use Rap2hpoutre\FastExcel\FastExcel;
(new FastExcel($rows))
->escapeFormulas()
->export('orders.xlsx');
This is a straightforward mitigation for CSV/formula injection, a risk that is easy to overlook in report-generation code.
Compatibility and Installation
Fast Excel 5 requires PHP 8.0+ and Laravel 6–13. It uses OpenSpout 4. Projects still on Fast Excel 2 (PHP 7 / Laravel 5) need to plan the dependency upgrade separately, as the major-version history includes a move from box/spout to openspout/openspout and a PHP 8 minimum.
Install via Composer:
composer require rap2hpoutre/fast-excel
Key Takeaways
importLazy()streams rows throughLazyCollection, avoiding full in-memory loadsheaderRow()+startRow()+limitRows()enable safe, paginated queue-based importssheet()andonlyColumns()scope imports to exactly the data you needescapeFormulas()prevents formula injection in user-data exports- Requires PHP 8.0+ and Laravel 6+; uses OpenSpout 4
Source: Fast Excel 5.x Adds Streaming Imports and Safer Exports — Laravel News