PHPackages                             filipefernandes/laravel-turbo-excel - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [PDF &amp; Document Generation](/categories/documents)
4. /
5. filipefernandes/laravel-turbo-excel

ActiveLibrary[PDF &amp; Document Generation](/categories/documents)

filipefernandes/laravel-turbo-excel
===================================

Blazing fast, memory-efficient Excel and CSV exports/imports for Laravel powerd by OpenSpout.

1.2.0(1mo ago)7406↓38.9%MITPHPPHP ^8.4CI passing

Since Apr 8Pushed 1mo agoCompare

[ Source](https://github.com/filipefernandes9747/laravel-turbo-excel)[ Packagist](https://packagist.org/packages/filipefernandes/laravel-turbo-excel)[ RSS](/packages/filipefernandes-laravel-turbo-excel/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (2)Dependencies (9)Versions (19)Used By (0)

Laravel Turbo Excel
===================

[](#laravel-turbo-excel)

[![Tests](https://github.com/filipefernandes/laravel-turbo-excel/actions/workflows/tests.yml/badge.svg)](https://github.com/filipefernandes/laravel-turbo-excel/actions)[![PHP](https://camo.githubusercontent.com/80c4564163cef31b2a66baaeb95a5bf4a418bcb5242a5ae707b94c2f4811e742/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e342532422d626c7565)](https://php.net)[![Laravel](https://camo.githubusercontent.com/db6ab190f654cef1221387c5810efb41afe136a460d01ad39055f3e03163514d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d31322e302d726564)](https://laravel.com)

Memory-efficient Excel and CSV **exports and imports** for Laravel, powered by [openspout/openspout](https://github.com/openspout/openspout).

Export and import classes implement lightweight **Concern interfaces** — the same pattern as Laravel Excel — giving you full control with zero magic.

---

Installation
------------

[](#installation)

```
composer require filipefernandes/laravel-turbo-excel
```

---

Performance Benchmark
---------------------

[](#performance-benchmark)

When measured against `maatwebsite/excel` (powered by PhpSpreadsheet), TurboExcel consistently demonstrates massive reductions in memory overhead while streaming exports directly to the disk. Below are the results of a standard benchmark comparing both packages running the exact same export structures.

### Data Source: Database Query (`FromQuery`)

[](#data-source-database-query-fromquery)

*(Both utilizing `WithChunkSize`, memory limit disabled)*

Dataset SizeRowsPackageTime (seconds)Peak MemoryOOM Risk?**Small**1,000`turbo-excel`\*\*~ 0.5s\*\*\*\*~ 1 MB\*\*🟢 None`maatwebsite`~ 2.5s~ 28 MB🟢 None**Medium**10,000`turbo-excel`\*\*~ 4.0s\*\*\*\*~ 1 MB\*\*🟢 None`maatwebsite`~ 25.0s~ 60 MB🟡 Moderate**Large**100,000`turbo-excel`\*\*~ 45.0s\*\*\*\*~ 1 MB\*\*🟢 None`maatwebsite`&gt; 150.0s&gt; 300 MB🔴 High**Enormous**500,000`turbo-excel`\*\*~ 220.0s\*\*\*\*~ 1 MB\*\*🟢 None`maatwebsite`*Crashes**Exhausted*🛑 Guaranteed*Note: TurboExcel keeps an entirely flat memory profile because OpenSpout immediately writes XML nodes sequentially to disk without buffering sheet contents in memory.*

---

Core Concept
------------

[](#core-concept)

Create a plain PHP class and implement the concerns you need:

```
// app/Exports/UsersExport.php

use TurboExcel\Concerns\FromQuery;
use TurboExcel\Concerns\WithHeadings;
use TurboExcel\Concerns\WithMapping;
use TurboExcel\Concerns\WithTitle;
use TurboExcel\Concerns\WithChunkSize;

class UsersExport implements FromQuery, WithTitle, WithHeadings, WithMapping, WithChunkSize
{
    public function query(): Builder
    {
        return User::query()->where('active', true);
    }

    public function title(): string   { return 'Active Users'; }

    public function headings(): array { return ['Name', 'Email', 'Joined']; }

    public function map($row): array
    {
        return [$row->name, $row->email, $row->created_at->format('Y-m-d')];
    }

    public function chunkSize(): int { return 500; }
}
```

Then call it from a controller:

```
use TurboExcel\Facades\TurboExcel;

// Stream directly to browser (Fastest, zero-IO)
return TurboExcel::stream(new UsersExport(), 'users.xlsx');

// Stream to browser via local temporary file
return TurboExcel::download(new UsersExport(), 'users.xlsx');

// Write to a Storage disk
TurboExcel::store(new UsersExport(), 'exports/users.xlsx', disk: 's3');

// Write to the filesystem
TurboExcel::export(new UsersExport(), storage_path('exports/users.xlsx'));
```

### Or using the `Exportable` trait

[](#or-using-the-exportable-trait)

Add the `Exportable` trait to your export class to trigger exports fluently:

```
use TurboExcel\Concerns\Exportable;

class UsersExport implements FromQuery
{
    use Exportable;
    // ...
}

// Then in your controller:
return (new UsersExport())->download('users.xlsx');
```

---

Data Source Concerns
--------------------

[](#data-source-concerns)

Implement **one** of the following to tell Turbo-Excel where your data comes from.

| `FromQuery` | `query(): Builder` | Large datasets — streamed via `lazy()`, flat memory | | `FromCollection` | `collection(): Collection` | Small, pre-loaded Illuminate Collections | | `FromArray` | `array(): array` | Plain PHP arrays | | `FromGenerator` | `generator(): \Generator` | Custom lazy sources, external API pages |

### `WithLimit`

[](#withlimit)

Cap the number of rows exported (useful for "Top 10" reports or sample files):

```
class TopUsersExport implements FromQuery, WithLimit
{
    public function limit(): int { return 100; }
}
```

---

Formatting Concerns
-------------------

[](#formatting-concerns)

### `WithHeadings`

[](#withheadings)

Explicit column headers written as the first row:

```
class UsersExport implements FromArray, WithHeadings
{
    public function headings(): array { return ['Full Name', 'Email']; }
    // ...
}
```

> If `WithHeadings` is **not** implemented, headings are auto-derived from the first row's array keys.

### `WithMapping`

[](#withmapping)

Transform each row before it is written. Combine with `WithHeadings` for labelled columns:

```
class UsersExport implements FromQuery, WithHeadings, WithMapping
{
    public function headings(): array { return ['Name', 'Email', 'Joined']; }

    public function map($user): array
    {
        return [$user->name, $user->email, $user->created_at->toDateString()];
    }
}
```

### `WithTitle`

[](#withtitle)

Set the sheet tab name (XLSX only):

```
class UsersExport implements FromArray, WithTitle
{
    public function title(): string { return 'Users'; }
}
```

### `WithChunkSize`

[](#withchunksize)

Override the default chunk size when using `FromQuery`:

```
class BigExport implements FromQuery, WithChunkSize
{
    public function chunkSize(): int { return 2000; }
}
```

### `WithColumnFormatting` (XLSX only)

[](#withcolumnformatting-xlsx-only)

Set native Excel number formats (Currency, Dates, etc.) without losing precision:

```
use TurboExcel\Concerns\WithColumnFormatting;

class FinancialExport implements FromArray, WithColumnFormatting
{
    public function array(): array { ... }

    public function columnFormats(): array
    {
        return [
            'B' => '#,##0.00 €', // Using column letter
            2   => 'dd/mm/yyyy', // Using 0-based index
        ];
    }
}
```

### `WithStyles` (XLSX only)

[](#withstyles-xlsx-only)

Apply rich visual styles (fonts, colors, borders) while streaming row-by-row (zero memory overhead):

```
use TurboExcel\Concerns\WithStyles;
use OpenSpout\Common\Entity\Style\Style;

class StyledExport implements FromArray, WithStyles
{
    public function array(): array { ... }

    public function styles(): array
    {
        return [
            // Style the special first header row
            'header' => (new Style())->setFontBold()->setBackgroundColor('FFE6E6E6'),

            // Style an entire column
            'A' => (new Style())->setFontItalic(),
        ];
    }
}
```

### `WithColumnWidths` (XLSX only) 📏

[](#withcolumnwidths-xlsx-only-)

Set manual column widths to ensure data readability:

```
use TurboExcel\Concerns\WithColumnWidths;

class WideExport implements FromArray, WithColumnWidths
{
    public function columnWidths(): array
    {
        return [
            'A' => 15,
            'B' => 45, // Perfect for email addresses
        ];
    }
}
```

### `WithProperties` (XLSX only) 📄

[](#withproperties-xlsx-only-)

Set professional document metadata:

```
use TurboExcel\Concerns\WithProperties;

class ProfessionalExport implements FromArray, WithProperties
{
    public function properties(): array
    {
        return [
            'title'   => 'Financial Report',
            'creator' => 'Acme Corp ERP',
            'subject' => 'Quarterly Analysis',
        ];
    }
}
```

### `WithCsvOptions` (CSV only)

[](#withcsvoptions-csv-only)

Customize delimiter, enclosure, and Unicode BOM settings for CSV files:

```
use TurboExcel\Concerns\WithCsvOptions;

class CustomCsvExport implements FromQuery, WithCsvOptions
{
    public function query() { ... }

    public function delimiter(): string { return ';'; }
    public function enclosure(): string { return "'"; }
    public function addBom(): bool      { return true; } // Better UTF-8 support in Excel
}
```

### `WithStrictNullComparison` 🎯

[](#withstrictnullcomparison-)

Ensures `null` values are explicitly handled without loose type conversion to empty strings.

---

Utility Concerns
----------------

[](#utility-concerns)

### `WithTranslation` 🌍

[](#withtranslation-)

Automatically localize your headings (Export) or header keys (Import) via Laravel's `trans()` helper:

```
class LocalizedExport implements WithHeadings, WithTranslation
{
    public function headings(): array { return ['users.id', 'users.name']; }
}
```

### `WithErrorHandling` 🚦

[](#witherrorhandling-)

Unified error handling for both sides of the pipeline:

```
class RobustProcess implements WithErrorHandling
{
    public function handleError(\Throwable $e): void
    {
        \Log::error($e->getMessage());
    }
}
```

### `WithAnonymization` 🛡️

[](#withanonymization-️)

Declaratively mask sensitive data (PII/GDPR) across your **exports and imports** without cluttering your mapping logic. It uses a high-performance in-place replacement loop.

```
use TurboExcel\Concerns\WithAnonymization;

class UsersProcess implements WithAnonymization
{
    // Optional: Determine if anonymization should run
    public function isAnonymizationEnabled(): bool
    {
        return app()->environment('production');
    }

    public function anonymizeColumns(): array
    {
        return ['email', 'phone_number', 'address'];
    }

    public function anonymizeReplacement(): string
    {
        return '[HIDDEN]';
    }
}
```

---

Multi-Sheet Exports (XLSX only)
-------------------------------

[](#multi-sheet-exports-xlsx-only)

Implement `WithMultipleSheets` and return an array of sheet export objects. Each sheet object may implement any concern independently.

```
TurboExcel::download(new ReportExport(), 'monthly-report.xlsx');
```

### `WithQuerySplitBySheet` ⚡

[](#withquerysplitbysheet-)

Optimized for large datasets sitting in a single flat table. It uses **one single ordered query** and automatically splits it into multiple sheets. You can return different sheet handler objects for different segments of the query.

Important

Your query **must be ordered** by the column you are splitting by.

```
use TurboExcel\Concerns\WithQuerySplitBySheet;
use TurboExcel\Concerns\WithHeadings;
use TurboExcel\Concerns\WithMapping;
use TurboExcel\Concerns\WithTitle;

class FastMultiSheetExport implements WithQuerySplitBySheet
{
    public function query()
    {
        // 1. Query must be ordered
        return DB::table('reports')->orderBy('category');
    }

    public function splitByColumn(): string
    {
        // 2. The column triggers a new sheet whenever its value changes
        return 'category';
    }

    public function sheet(mixed $row): object
    {
        // 3. Return a handler for this sheet.
        // It can implement any concern (Headings, Mapping, Styles, etc.)
        return match($row->category) {
            'VIP'      => new VipSheetHandler(),
            'Standard' => new StandardSheetHandler(),
            default    => new DefaultSheetHandler(),
        };
    }
}

class VipSheetHandler implements WithTitle, WithHeadings, WithMapping
{
    public function title(): string   { return '⭐ VIP Report'; }
    public function headings(): array { return ['VIP Name', 'Priority']; }
    public function map($row): array  { return [$row->name, $row->level]; }
}
```

---

Output Methods
--------------

[](#output-methods)

MethodDescription`TurboExcel::stream($export, 'file.xlsx')`Stream directly to browser (Fastest, zero-IO)`TurboExcel::download($export, 'file.xlsx')`Stream to browser via local temporary file`TurboExcel::store($export, 'path/file.xlsx', 's3')`Write to a Storage disk`TurboExcel::export($export, '/abs/path/file.xlsx')`Write to filesystem path`TurboExcel::queue($export, 'path/file.xlsx', 's3')`Dispatch to a Laravel Queue**Import**

MethodDescription`TurboExcel::import($import, '/abs/path.csv', ?Format)`Stream import from a filesystem path — returns `TurboExcel\Import\Result` when synchronous, or `Illuminate\Bus\Batch` when the import uses `TurboExcel\Import\Concerns\ShouldQueue` (see [Imports](#imports-csv--xlsx))The export format is auto-detected from the filename extension (`.xlsx` → XLSX, `.csv` → CSV). Pass an explicit `Format` case to override:

```
use TurboExcel\Enums\Format;

TurboExcel::download(new UsersExport(), 'users.xlsx', Format::CSV);
```

---

Imports (CSV &amp; XLSX)
------------------------

[](#imports-csv--xlsx)

Imports are **streamed** row-by-row for predictable memory use. Internally, CSV is read with PHP’s `fgetcsv`; XLSX is read with OpenSpout on the **first worksheet only**. Readers always yield **0-indexed cell arrays** (`0 => 'Alice', 1 => 'alice@example.com'`). Associative rows and header logic run in the import **pipeline** only when you opt in via concerns — nothing assumes a header row unless you implement `WithHeaderRow`.

### Basic usage

[](#basic-usage)

```
use TurboExcel\Facades\TurboExcel;
use TurboExcel\Import\Concerns\ToModel;
use TurboExcel\Import\Concerns\WithHeaderRow;
use TurboExcel\Import\Concerns\WithMapping;
use TurboExcel\Import\Concerns\WithNormalizedHeaders;
use TurboExcel\Import\Concerns\WithValidation;

class UsersImport implements ToModel, WithHeaderRow, WithNormalizedHeaders, WithMapping, WithValidation
{
    public function headerRow(): int
    {
        return 1;
    }

    public function headerNormalization(): array|callable
    {
        return fn (string $header): string => strtolower(trim($header));
    }

    public function map(array $row): array
    {
        return [
            'name'  => trim($row['name']),
            'email' => strtolower($row['email']),
        ];
    }

    public function rules(): array
    {
        return [
            'email' => 'required|email',
        ];
    }

    public function model(array $row): ?User
    {
        return new User($row);
    }
}

$result = TurboExcel::import(new UsersImport(), storage_path('imports/users.csv'));
```

You can also return a **fixed map** from trimmed spreadsheet headers to attribute keys (any header not listed keeps the trimmed text as the key):

```
public function headerNormalization(): array
{
    return [
        'FULL NAME'     => 'name',
        'Email Address' => 'email',
    ];
}
```

When the import runs **synchronously**, `$result` is a `TurboExcel\Import\Result`:

PropertyMeaning`processed`Rows that completed the pipeline (validation + persist / collection append, if applicable)`failed`Rows that failed but were handled via `SkipsOnFailure``rows``Illuminate\Support\Collection` of associative arrays (after **map** + **validate**) when the import (or any sheet import in a multi-sheet run) uses `ToCollection`. Multi-sheet sync imports **concatenate** sheets in workbook order; otherwise `null`The file format is inferred from the extension (`.csv` / `.xlsx`). Pass an explicit `TurboExcel\Enums\Format` as the third argument to override.

### Import concerns (`TurboExcel\Import\Concerns`)

[](#import-concerns-turboexcelimportconcerns)

ConcernRole`ToModel``model(array $row): ?Model` — return `null` to skip persisting that row`ToCollection`Marker: each successful row is pushed onto `$result->rows`. **Not compatible with `ShouldQueue`.**`ToArray`Marker: similar to `ToCollection` but returns a plain PHP array.`OnEachRow``onRow(array $row): void` — process each row instantly via callback`OnEachChunk``onChunk(Collection $chunk): void` — process parsed rows in raw chunks`WithMapping``map(array $row): array` — transform the row before validation / persistence`WithValidation``rules(): array` — Laravel validator rules`SkipsOnValidation``onValidationFailed(ValidationException $e)` — Gracefully handle bad data`WithHeaderRow``headerRow(): int` — 1-based row index of the header`WithNormalizedHeaders``headerNormalization()` — transform header text into array keys`WithRowFilter``filterRow(array $row): bool` — Skip rows before mapping/validation`WithChunkReading``chunkSize(): int` — configure scan chunks for queues`ShouldQueue`Marker: run the import via the queue`SkipsOnFailure``onFailure(array $row, \Throwable $e): void` — record failures and continue`WithBatchSize``batchSize(): int` — Enhanced alias for `WithBatchInserts``WithInsertStrategy``insertStrategy(): InsertStrategy` — Choose `INSERT`, `UPDATE`, or `UPSERT``WithMetrics`Marker: logs memory and timing to your Laravel log`Importable`Trait: adds fluent methods like `import()` and `queue()``RemembersFullRow``setFullRow(array $row)` — access raw, unmapped input data`RemembersRowNumber`tracks the physical row index`WithMultipleSheets`**XLSX only.** Process multiple worksheets in one workbookPipeline order per row: optional header → associative combine → **map** → **validate** → **model** / batch insert, and **append to `$result->rows`** when `ToCollection` is implemented.

### Multi-sheet XLSX imports

[](#multi-sheet-xlsx-imports)

```
use TurboExcel\Import\Concerns\WithMultipleSheets;

class WorkbookImport implements WithMultipleSheets
{
    public function sheets(): array
    {
        return [
            new UsersSheetImport(),   // first worksheet
            new OrdersSheetImport(),  // second worksheet
        ];
    }
}

$result = TurboExcel::import(new WorkbookImport(), storage_path('workbook.xlsx'));
// $result->processed / $result->failed are totals across all sheets
// $result->rows concatenates rows from each sheet import that uses ToCollection
```

Queued multi-sheet imports dispatch one or more chunk jobs **per sheet** (each job carries a `sheetIndex` on `XlsxReadSegment`). `WithChunkReading` / `chunkSize()` are read from **each sheet’s** import object when present.

### CSV options &amp; BOM

[](#csv-options--bom)

- Implement `TurboExcel\Concerns\WithCsvOptions` on the import class to set **delimiter** and **enclosure** (same concern as exports).
- A **UTF-8 BOM** (`EF BB BF`) is consumed only when the reader opens the file at **byte offset 0**, so the first column is not corrupted. Chunk jobs that start later in the file do not strip the BOM again.

### Queued &amp; chunked imports

[](#queued--chunked-imports)

If your import implements `TurboExcel\Import\Concerns\ShouldQueue`:

- **`ToCollection` is not supported** with queued imports (there is no single merged `Collection` across workers). Remove `ShouldQueue` or use `ToModel` / a synchronous import.
- With **`WithChunkReading`**, TurboExcel performs one **scan** of the file, then dispatches `TurboExcel\Import\Jobs\ProcessChunkJob` instances inside a **`Illuminate\Bus\Batch`**. **CSV** chunks use **byte ranges** in the raw file; **XLSX** chunks use **inclusive row index ranges** per worksheet (`XlsxReadSegment` includes a 0-based `sheetIndex`).
- Without `WithChunkReading`, a **single** queued job processes the whole file (or **one job per sheet** when using import `WithMultipleSheets`).

The `import()` method returns an `Illuminate\Bus\Batch` when jobs are dispatched. Each job increments cache counters under:

- `turbo_excel_import:{uuid}:processed`
- `turbo_excel_import:{uuid}:failed`

(The UUID is shared by all jobs in that batch.) If the file has **no data rows** (for example header-only CSV), you get a `Result` with zero counts and **no** batch is dispatched.

---

Format Enum
-----------

[](#format-enum)

```
use TurboExcel\Enums\Format;

Format::XLSX  // application/vnd.openxmlformats-...
Format::CSV   // text/csv
```

---

Queued Background Exports
-------------------------

[](#queued-background-exports)

When exporting massive amounts of data, you can dispatch the export to a Laravel Queue entirely in the background. Because `TurboExcel` uses `OpenSpout`, memory is kept incredibly flat, handling millions of rows efficiently within a single job.

```
TurboExcel::queue(new UsersExport(), 'reports/huge-report.xlsx', 's3')
    ->onConnection('redis')
    ->onQueue('exports');
```

**Using with Laravel Batches (Progress Tracking)**

You can also dispatch the export job directly inside a Laravel Batch to track completion percentages! `TurboExcel` automatically breaks your data into chunks and updates the batch progress internally as it writes to the file.

```
use Illuminate\Support\Facades\Bus;
use TurboExcel\Jobs\ExportJob;

$batch = Bus::batch([
    new ExportJob(new UsersExport(), 'reports/users.xlsx', disk: 's3')
])->name('Daily Users Export')->dispatch();

// Later check progress in your UI
echo $batch->progress(); // e.g. 50%
```

---

Debugging / Profiling
---------------------

[](#debugging--profiling)

When dealing with extremely large datasets (millions of rows) in local development, it can be useful to see exactly how much memory the OpenSpout stream is consuming and how fast the database is chunking rows.

Implement the `TurboExcel\Concerns\WithDebug` interface on your export class to automatically emit detailed debugging logs to your default Laravel Log (`storage/logs/laravel.log`).

---

Testing
-------

[](#testing)

```
composer test
```

---

License
-------

[](#license)

MIT

###  Health Score

48

—

FairBetter than 94% of packages

Maintenance89

Actively maintained with recent releases

Popularity23

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity60

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

18

Last Release

56d ago

Major Versions

0.0.7 → 1.0.02026-04-10

PHP version history (2 changes)0.0.1PHP ^8.2

1.0.0PHP ^8.4

### Community

Maintainers

![](https://www.gravatar.com/avatar/44c4a0ab684a6ff2f571c5b6b1db79320570f053120dadb2793c9b8ee41529a3?d=identicon)[filipe9747](/maintainers/filipe9747)

---

Top Contributors

[![filipefernandes9747](https://avatars.githubusercontent.com/u/22693486?v=4)](https://github.com/filipefernandes9747 "filipefernandes9747 (1 commits)")

---

Tags

streamlaravelexportexcelxlsxcsvfastopenspout

###  Code Quality

TestsPest

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/filipefernandes-laravel-turbo-excel/health.svg)

```
[![Health](https://phpackages.com/badges/filipefernandes-laravel-turbo-excel/health.svg)](https://phpackages.com/packages/filipefernandes-laravel-turbo-excel)
```

###  Alternatives

[maatwebsite/excel

Supercharged Excel exports and imports in Laravel

12.7k152.8M844](/packages/maatwebsite-excel)[rap2hpoutre/fast-excel

Fast Excel import/export for Laravel

2.3k26.3M50](/packages/rap2hpoutre-fast-excel)[laravel/scout

Laravel Scout provides a driver based solution to searching your Eloquent models.

1.7k53.0M578](/packages/laravel-scout)[psalm/plugin-laravel

Psalm plugin for Laravel

3325.1M337](/packages/psalm-plugin-laravel)[avadim/fast-excel-laravel

Lightweight and very fast XLSX Excel Spreadsheet Export/Import for Laravel

4254.7k1](/packages/avadim-fast-excel-laravel)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
