Download the PHP package rap2hpoutre/fast-excel without Composer
On this page you can find all versions of the php package rap2hpoutre/fast-excel. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Informations about the package fast-excel
Fast Excel import/export for Laravel, thanks to Spout. See benchmarks below.
Quick start
Install via composer:
Export a Model to .xlsx file:
Export
Export a Model, Query or Collection:
Export xlsx, ods and csv:
Export only some attributes specifying columns names:
Hide columns from the exported file while still being able to use them inside the
callback, using hideColumnsPrefixedWith(). This is handy for callback-only data
(lookups, computed flags, etc.) that should not appear as a column:
Columns are hidden from both the header row and every data row. The prefix
defaults to _, and any other one can be used — hideColumnsPrefixedWith('tmp_').
Hiding is opt-in: unless you call this method, every column is exported, so
columns that already start with an underscore keep working as before.
Download (from a controller method):
Import
import returns a Collection:
Import a csv with specific delimiter, enclosure characters and "gbk" encoding:
Import and insert to database:
Limit the number of data rows imported with limitRows (headers excluded). It works with both import and importLazy:
Start reading at a given row with startRow. On its own, startRow also treats
that row as the header row. Use headerRow to read the headers from their real
position while data starts further down:
Together with limitRows, that is how a large file is imported in chunks — one
slice per job run, each with the correct header names:
headerRow is opt-in: without it, startRow keeps its previous behaviour of
using the start row as the header row.
Truncate each imported row after a given column with limitColumns, which takes
either a column reference or a number of columns:
This is useful for files where formatting has been applied to entire rows: the
spreadsheet then reports thousands of trailing cells that look like real columns,
and importing them yields empty column_9, column_10… entries on every row.
Those cells are dropped from the imported collection (OpenSpout still parses the
sheet). Like limitRows, it works with both import and importLazy.
Keep specific columns (and drop everything else, including middle empties) with
onlyColumns. Letters and 1-based indexes can be mixed; order is preserved:
onlyColumns and limitColumns cannot both be active — setting one clears the other.
Passing null only clears that setter and leaves the other alone.
Facades
You may use FastExcel with the optional Facade. Add the following line to config/app.php under the aliases key.
``
Using the Facade, you will not have access to the constructor. You may set your export data using the data method.
``
Global helper
FastExcel provides a convenient global helper to quickly instantiate the FastExcel class anywhere in a Laravel application.
Advanced usage
Export multiple sheets
Export multiple sheets by creating a SheetCollection:
Use index to specify sheet name:
Import multiple sheets
Import multiple sheets by using importSheets:
You can also import a specific sheet by its number:
sheet() also accepts a sheet name, so you can select a sheet without knowing its position:
Import multiple sheets with sheets names:
Use withSheetContext() to receive the current sheet name as the first argument
of the importSheets callback — handy when the same field names need to be
handled differently per sheet:
Export large collections (low memory)
Passing a materialized collection (User::all(), ->get(), collect([...])) loads every
row into memory before the export starts, so it grows with the size of the data and a
large enough dataset fails outright with Allowed memory size of N bytes exhausted. Feed a
lazy source instead and peak memory stays flat, whatever the row count.
Eloquent's cursor() (or ->lazy()) returns a
LazyCollection, which FastExcel
streams row by row — no wrapper needed:
For any other source, hand export() a generator using yield:
Exporting 1,000,000 rows (4 columns) under a 512 MB memory_limit:
| How you export | Peak memory | Result |
|---|---|---|
export() from a materialized collection |
> 512 MB | fails once it exceeds memory_limit |
export() from a cursor / generator (streaming) |
~4 MB | always completes |
Streaming does not change export speed (that is dominated by the underlying
OpenSpout writer) — it is what keeps memory flat
so very large files finish at all. transpose() cannot stream, as it must buffer the whole
dataset to pivot rows and columns.
Import large files (low memory)
import returns a Collection containing every row, so memory grows with the size of
the file. On a file larger than your PHP memory_limit, the default import() fails
outright with Allowed memory size of N bytes exhausted. To import a large file
without running out of memory, pass a callback and return null — each row is
then processed but not accumulated, so memory stays flat:
If the callback returns a value (for example the created model), that value is collected and returned to you — handy for small files, but it keeps every row in memory. Return
nullwhen you only need the side effect (e.g. inserting rows).
Importing a 730,000-row file (8 columns), measured under a constrained
memory_limit:
| How you import | Peak memory | Result |
|---|---|---|
import($file) (returns a Collection) |
~440 MB | fails once it exceeds memory_limit |
import($file, fn ($row) => null) (streaming) |
~4 MB | always completes |
Reading speed is the same either way — it is dominated by the underlying OpenSpout parser, not by how the rows are returned. The difference above is memory, which is what lets very large files finish at all.
If you would rather keep working with the rows than process them inside a callback,
importLazy returns a LazyCollection
that streams rows one at a time — you get the full Collection API while memory stays
flat:
importLazy accepts the same optional callback as import, and honors sheet(),
withoutHeaders(), and header de-duplication. Transposing (transpose()) is not
supported with lazy import.
Add header and rows style
Add header and rows style with headerStyle and rowsStyle methods.
You can also style each header column individually with setHeaderColumnStyles
(the header-row counterpart of setColumnStyles). Keys are the zero-based
column positions:
Set column widths
Column widths are an OpenSpout writer option, so they are set through
configureOptionsUsing. Widths are expressed in Excel's own unit (roughly the
number of characters that fit), and column numbers are 1-based:
Use setColumnWidthForRange for a contiguous span:
This works with streaming exports (cursors and generators) as well, since widths are written when the file is finalized rather than per row.
Only xlsx and ods support widths. csv has no notion of column width, and
OpenSpout\Writer\CSV\Options does not define setColumnWidth() at all — calling
it on a csv export raises Error: Call to undefined method. If the same code path
can export either format, guard the call:
Note that widths are explicit — there is no automatic sizing to fit the content.
Export values as strings or numbers
By default numbers are written as numbers and strings as strings. Use
stringValues() to force every value to a text cell — handy to keep leading
zeros or long numeric IDs (e.g. phone numbers) intact:
Need finer control? setColumnFormat() overrides the type per column and takes
precedence over stringValues():
Escape formulas (prevent formula injection)
By default any string starting with = (e.g. =1+2) is written as a live
formula cell, which can corrupt the file or enable CSV/formula injection. Call
escapeFormulas() to write string values as literal text cells instead:
Skip rows during export
If the export callback returns null or false for a row, that row is
skipped entirely and does not appear in the output file:
Use raw OpenSpout Cell instances
For full control over a single cell's type or style, a row value may be an
OpenSpout\Common\Entity\Cell instance. It is written through as-is, while the
other (scalar) values in the row keep their normal handling:
Why?
FastExcel is intended at being Laravel-flavoured Spout: a simple, but elegant wrapper around Spout with the goal of simplifying imports and exports. It could be considered as a faster (and memory friendly) alternative to Laravel Excel, with less features. Use it only for simple tasks.
Benchmarks
XLSX export of 10,000 rows × 20 columns of random data, average of 10 runs (PHP 8.4, July 2026). Don't trust benchmarks.
| Peak memory | Execution time | |
|---|---|---|
| Laravel Excel 3.1 | 218 MB | 2.53 s |
| FastExcel — collection | 42 MB | 0.90 s |
| FastExcel — generator | 4 MB | 0.93 s |
FastExcel streams rows through OpenSpout instead of building the whole
spreadsheet in memory. Feed it a generator (or importLazy() on the read side) and peak memory stays flat no matter how
many rows you export — here about 55× less than Laravel Excel. Reproduce with
bench/readme-export-bench.php.
Still, remember that Laravel Excel has many more features.
All versions of fast-excel with dependencies
illuminate/support Version ^6.0 || ^7.0 || ^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0 || ^13.0
openspout/openspout Version ^4.24