Search by

abolfazrastegar / laravel-excel-exporter

A powerful and flexible Excel/CSV exporter for Laravel applications.

Maintainers

Package info

github.com/abolfazlrastegar/laravel-excel-exporter

pkg:composer/abolfazrastegar/laravel-excel-exporter

Transparency log

Statistics

Installs: 2

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

v1.0.0 2026-09-07 07:44 UTC

This package is auto-updated.

Last update: 2026-09-07 12:50:16 UTC


README

alt text

Laravel Excel Exporter

Latest Version Total Downloads License PHP Version

A powerful, flexible and developer-friendly Excel/CSV exporter for Laravel applications.

Built on top of PhpSpreadsheet, this package provides a fluent API for exporting:

  • Eloquent Models
  • Eloquent Query Builder
  • Laravel Query Builder
  • Collections
  • Arrays
  • Iterables
  • Nested relationships
  • Custom callbacks
  • XLSX files
  • CSV files
  • Large datasets
  • Queue-based exports
  • RTL / Persian Excel files

Table of Contents

Requirements

  • PHP ^8.2
  • Laravel 10.x
  • Laravel 11.x
  • Laravel 12.x
  • Laravel 13.x
  • PhpSpreadsheet ^5.9

Laravel 10+ is supported.

Installation

Install the package using Composer:

composer require abolfazrastegar/laravel-excel-exporter

Laravel Package Discovery automatically registers the service provider and facade.

No additional configuration is required for basic usage.

Basic Usage

The package provides a fluent API.

use ARExcel;

return ARExcel::make()
    ->from(User::query())
    ->columns([
        'id' => 'ID',
        'name' => 'Name',
        'email' => 'Email',
    ])
    ->xlsx()
    ->download();

This creates an XLSX file and downloads it to the browser.

Export an Eloquent Model

use App\Models\User;
use ARExcel;

return ARExcel::make()
    ->from(User::query())
    ->columns([
        'id' => 'ID',
        'name' => 'Name',
        'email' => 'Email',
    ])
    ->xlsx()
    ->filename('users.xlsx')
    ->download();

Export a Query Builder

use Illuminate\Support\Facades\DB;
use ARExcel;

return ARExcel::make()
    ->from(
        DB::table('users')
            ->select([
                'id',
                'name',
                'email',
            ])
    )
    ->columns([
        'id' => 'ID',
        'name' => 'Name',
        'email' => 'Email',
    ])
    ->xlsx()
    ->download();

Export an Array

You can export normal PHP arrays.

$data = [
    [
        'id' => 1,
        'name' => 'Abolfazl',
        'email' => 'abolfazl@example.com',
    ],
    [
        'id' => 2,
        'name' => 'Ali',
        'email' => 'ali@example.com',
    ],
];

return ARExcel::make()
    ->from($data)
    ->columns([
        'id' => 'ID',
        'name' => 'Name',
        'email' => 'Email',
    ])
    ->xlsx()
    ->download();

Export a Collection

$users = User::query()
    ->where('active', true)
    ->get();

return ARExcel::make()
    ->from($users)
    ->columns([
        'id' => 'ID',
        'name' => 'Name',
        'email' => 'Email',
    ])
    ->xlsx()
    ->download();

For large datasets, prefer using a Query Builder instead of loading the entire collection into memory.

CSV Export

To export a CSV file:

return ARExcel::make()
    ->from(User::query())
    ->columns([
        'id' => 'ID',
        'name' => 'Name',
        'email' => 'Email',
    ])
    ->csv()
    ->filename('users.csv')
    ->download();

The CSV writer includes UTF-8 BOM support, making Persian and Unicode data compatible with applications such as Microsoft Excel.

Persian / RTL Excel

For Persian, Arabic and other right-to-left languages:

return ARExcel::make()
    ->from(User::query())
    ->columns([
        'id' => 'شناسه',
        'name' => 'نام',
        'email' => 'ایمیل',
    ])
    ->xlsx()
    ->rtl()
    ->download();

The generated worksheet will use right-to-left layout.

Freeze Header

Freeze the first row:

return ARExcel::make()
    ->from(User::query())
    ->columns([
        'id' => 'شناسه',
        'name' => 'نام',
        'email' => 'ایمیل',
    ])
    ->xlsx()
    ->freezeHeader()
    ->download();

This is useful for large Excel files.

Auto Filter

Enable Excel's header filter:

return ARExcel::make()
    ->from(User::query())
    ->columns([
        'id' => 'شناسه',
        'name' => 'نام',
        'email' => 'ایمیل',
    ])
    ->xlsx()
    ->filter()
    ->download();

You can combine this with RTL and frozen headers:

return ARExcel::make()
    ->from(User::query())
    ->columns([
        'id' => 'شناسه',
        'name' => 'نام',
        'email' => 'ایمیل',
    ])
    ->xlsx()
    ->rtl()
    ->freezeHeader()
    ->filter()
    ->download();

Column Width

You can specify the width of each column:

return ARExcel::make()
    ->from(User::query())
    ->columns([
        'id' => [
            'title' => 'شناسه',
            'width' => 10,
        ],

        'name' => [
            'title' => 'نام',
            'width' => 30,
        ],

        'email' => [
            'title' => 'ایمیل',
            'width' => 40,
        ],
    ])
    ->xlsx()
    ->download();

Auto Size Columns

Auto-size columns based on their content:

return ARExcel::make()
    ->from(User::query())
    ->columns([
        'id' => 'شناسه',
        'name' => 'نام',
        'email' => 'ایمیل',
    ])
    ->xlsx()
    ->autoSize()
    ->download();

Auto-size is enabled by default.

To disable it:

->autoSize(false)

Nested Relationships

Nested Eloquent relationships are supported.

For example:

User::query()
    ->with('role')

Then:

return ARExcel::make()
    ->from(
        User::query()->with('role')
    )
    ->columns([
        'id' => 'شناسه',
        'name' => 'نام',
        'role.name' => 'نقش',
    ])
    ->xlsx()
    ->download();

Multiple Nested Relationships

return ARExcel::make()
    ->from(
        Order::query()
            ->with([
                'user',
                'product.category',
            ])
    )
    ->columns([
        'id' => 'شماره سفارش',
        'user.name' => 'مشتری',
        'product.title' => 'محصول',
        'product.category.name' => 'دسته‌بندی',
    ])
    ->xlsx()
    ->download();

Custom Column Callback

You can customize the exported value using a callback.

return ARExcel::make()
    ->from(User::query())
    ->columns([
        'id' => 'شناسه',

        'name' => [
            'title' => 'نام',
            'value' => fn ($user) => strtoupper($user->name),
        ],
    ])
    ->xlsx()
    ->download();

Boolean Values

Boolean values are automatically converted to:

true  → بله
false → خیر

Example:

return ARExcel::make()
    ->from(User::query())
    ->columns([
        'id' => 'شناسه',

        'name' => 'نام',

        'active' => [
            'title' => 'وضعیت',
        ],
    ])
    ->xlsx()
    ->download();

Date Formatting

Date columns can specify a format:

return ARExcel::make()
    ->from(User::query())
    ->columns([
        'id' => 'شناسه',

        'created_at' => [
            'title' => 'تاریخ ثبت',
            'format' => 'date',
        ],
    ])
    ->xlsx()
    ->download();

Available formats:

date
datetime
boolean

Sheet Name

You can define the worksheet name:

return ARExcel::make()
    ->from(User::query())
    ->columns([
        'id' => 'شناسه',
        'name' => 'نام',
    ])
    ->sheet('Users')
    ->xlsx()
    ->download();

For Persian:

->sheet('کاربران')

File Name

return ARExcel::make()
    ->from(User::query())
    ->columns([
        'id' => 'شناسه',
        'name' => 'نام',
    ])
    ->xlsx()
    ->filename('users.xlsx')
    ->download();

CSV:

->filename('users.csv')

Store Exported File

Instead of downloading the file, you can save it to a Laravel filesystem disk.

ARExcel::make()
    ->from(User::query())
    ->columns([
        'id' => 'شناسه',
        'name' => 'نام',
        'email' => 'ایمیل',
    ])
    ->xlsx()
    ->store(
        'exports/users.xlsx',
        'public'
    );

For the local disk:

ARExcel::make()
    ->from(User::query())
    ->columns([
        'id' => 'شناسه',
        'name' => 'نام',
    ])
    ->xlsx()
    ->store(
        'exports/users.xlsx',
        'local'
    );

Complete Persian Example

A complete example for a Persian Laravel application:

use App\Models\User;
use ARExcel;

public function exportUsers()
{
    return ARExcel::make()
        ->from(
            User::query()
                ->with('role')
                ->where('active', true)
        )
        ->columns([
            'id' => [
                'title' => 'شناسه',
                'width' => 10,
            ],

            'name' => [
                'title' => 'نام',
                'width' => 30,
            ],

            'mobile' => [
                'title' => 'موبایل',
                'width' => 20,
            ],

            'email' => [
                'title' => 'ایمیل',
                'width' => 40,
            ],

            'role.name' => [
                'title' => 'نقش',
                'width' => 20,
            ],

            'active' => [
                'title' => 'وضعیت',
            ],
        ])
        ->sheet('کاربران')
        ->xlsx()
        ->rtl()
        ->freezeHeader()
        ->filter()
        ->autoSize()
        ->filename('users.xlsx')
        ->download();
}

Large Dataset

For large datasets, use a Query Builder:

return ARExcel::make()
    ->from(
        User::query()
            ->with('role')
            ->orderBy('id')
    )
    ->columns([
        'id' => 'شناسه',
        'name' => 'نام',
        'email' => 'ایمیل',
        'role.name' => 'نقش',
    ])
    ->xlsx()
    ->download();

The exporter uses a cursor for Eloquent and Query Builder sources, which prevents the complete query result from being loaded into a PHP array.

XLSX generation still uses PhpSpreadsheet and therefore can consume significant memory for extremely large files. For very large datasets, CSV + streaming + queue is recommended.

Streaming CSV

For very large exports, CSV is generally a better choice.

return ARExcel::make()
    ->from(
        User::query()
            ->orderBy('id')
    )
    ->columns([
        'id' => 'شناسه',
        'name' => 'نام',
        'email' => 'ایمیل',
    ])
    ->csv()
    ->filename('users.csv')
    ->download();

CSV is particularly useful when exporting hundreds of thousands or millions of records.

Queue Export

For long-running exports, use Laravel queues.

First create an export definition:

namespace App\Exports;

use App\Models\User;
use Abolfazrastegar\LaravelExcelExporter\Contracts\ExportDefinition;

final class UsersExport implements ExportDefinition
{
    public function query(): mixed
    {
        return User::query()
            ->with('role')
            ->orderBy('id');
    }

    public function columns(): array
    {
        return [
            'id' => [
                'title' => 'شناسه',
                'width' => 10,
            ],

            'name' => [
                'title' => 'نام',
                'width' => 30,
            ],

            'email' => [
                'title' => 'ایمیل',
                'width' => 40,
            ],

            'role.name' => [
                'title' => 'نقش',
                'width' => 20,
            ],
        ];
    }
}

Then dispatch the export:

use ARExcel;
use App\Exports\UsersExport;

ARExcel::queue(
    UsersExport::class,
    'exports/users.xlsx',
    'public',
    'xlsx'
);

For CSV:

ARExcel::queue(
    UsersExport::class,
    'exports/users.csv',
    'public',
    'csv'
);

Make sure Laravel's queue worker is running:

php artisan queue:work

Queue with Redis

If your Laravel application uses Redis:

QUEUE_CONNECTION=redis

Then:

php artisan queue:work redis

The export will be processed by the queue worker instead of blocking the HTTP request.

Export Definition

For reusable exports, use ExportDefinition.

namespace App\Exports;

use App\Models\Order;
use Abolfazrastegar\LaravelExcelExporter\Contracts\ExportDefinition;

final class OrdersExport implements ExportDefinition
{
    public function query(): mixed
    {
        return Order::query()
            ->with([
                'user',
                'product',
            ])
            ->orderBy('id');
    }

    public function columns(): array
    {
        return [
            'id' => 'شماره سفارش',
            'user.name' => 'مشتری',
            'product.title' => 'محصول',
            'amount' => 'مبلغ',
            'created_at' => [
                'title' => 'تاریخ',
                'format' => 'datetime',
            ],
        ];
    }
}

This approach is recommended for exports that are reused or executed through queues.

Facade

The package provides the ARExcel facade:

use ARExcel;

Equivalent service usage:

use Abolfazrastegar\LaravelExcelExporter\ExcelExportService;

$excel = app(ExcelExportService::class);

return $excel
    ->make()
    ->from(User::query())
    ->columns([
        'id' => 'ID',
        'name' => 'Name',
    ])
    ->xlsx()
    ->download();

Available Methods

Data

->from($data)

Supported data:

Eloquent Builder
Query Builder
Collection
Array
Traversable

Columns

->columns([
    'id' => 'ID',
])

Or:

->columns([
    'id' => [
        'title' => 'ID',
        'width' => 10,
        'format' => 'number',
    ],
])

Output Type

XLSX:

->xlsx()

CSV:

->csv()

Worksheet

->sheet('Users')

RTL

->rtl()

Disable:

->rtl(false)

Freeze Header

->freezeHeader()

Disable:

->freezeHeader(false)

Filter

->filter()

Disable:

->filter(false)

Auto Size

->autoSize()

Disable:

->autoSize(false)

File Name

->filename('users.xlsx')

Download

->download()

Store

->store(
    'exports/users.xlsx',
    'public'
)

Example API Controller

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\User;
use ARExcel;

final class UserExportController extends Controller
{
    public function __invoke()
    {
        return ARExcel::make()
            ->from(
                User::query()
                    ->with('role')
                    ->orderBy('id')
            )
            ->columns([
                'id' => 'شناسه',
                'name' => 'نام',
                'mobile' => 'موبایل',
                'email' => 'ایمیل',
                'role.name' => 'نقش',
            ])
            ->xlsx()
            ->rtl()
            ->freezeHeader()
            ->filter()
            ->filename('users.xlsx')
            ->download();
    }
}

Route:

use App\Http\Controllers\Api\UserExportController;

Route::get(
    'users/export',
    UserExportController::class
);

Example with Filters

public function export(Request $request)
{
    $query = User::query()
        ->with('role');

    if ($request->filled('search')) {
        $query->where(function ($query) use ($request) {
            $query
                ->where('name', 'like', "%{$request->search}%")
                ->orWhere('email', 'like', "%{$request->search}%");
        });
    }

    if ($request->filled('active')) {
        $query->where(
            'active',
            $request->boolean('active')
        );
    }

    return ARExcel::make()
        ->from($query)
        ->columns([
            'id' => 'شناسه',
            'name' => 'نام',
            'email' => 'ایمیل',
            'role.name' => 'نقش',
        ])
        ->xlsx()
        ->rtl()
        ->freezeHeader()
        ->filter()
        ->filename('filtered-users.xlsx')
        ->download();
}

Testing

Install development dependencies:

composer install

Run PHPUnit:

composer test

Or:

vendor/bin/phpunit

Code Quality

Validate Composer:

composer validate --strict

Regenerate autoload files:

composer dump-autoload

Laravel Compatibility

Laravel PHP
10.x 8.2+
11.x 8.2+
12.x 8.2+
13.x 8.3+

The package itself requires:

PHP ^8.2

Architecture

The package is designed around a small set of responsibilities:

ARExcel
   │
   ▼
ExcelExportService
   │
   ▼
ExcelBuilder
   │
   ├── ExcelColumn
   │
   ├── XlsxWriter
   │      └── PhpSpreadsheet
   │
   ├── CsvWriter
   │
   └── StreamingCsvWriter

Queue exports use:

ExportDefinition
       │
       ▼
    ExportJob
       │
       ▼
 ExcelExportService
       │
       ▼
 ExcelBuilder

This keeps the export API independent from Laravel controllers.

Performance Recommendations

For small and medium datasets:

->xlsx()

For very large datasets:

->csv()

For long-running exports:

ARExcel::queue(...)

Recommended architecture:

Small Dataset
     │
     └── XLSX
          │
          └── Download

Large Dataset
     │
     └── CSV
          │
          └── Streaming

Very Large Dataset
     │
     ├── CSV
     ├── Streaming
     └── Queue

Error Handling

The package provides custom exceptions.

use Abolfazrastegar\LaravelExcelExporter\Exceptions\ExportException;
use Abolfazrastegar\LaravelExcelExporter\Exceptions\InvalidExportDataException;

Example:

try {
    return ARExcel::make()
        ->from(User::query())
        ->columns([
            'id' => 'ID',
            'name' => 'Name',
        ])
        ->xlsx()
        ->download();

} catch (InvalidExportDataException $e) {
    report($e);

    return response()->json([
        'message' => $e->getMessage(),
    ], 422);

} catch (ExportException $e) {
    report($e);

    return response()->json([
        'message' => 'Export failed.',
    ], 500);
}

Contributing

Contributions are welcome.

  1. Fork the repository.
  2. Create a feature branch.
  3. Add tests for your changes.
  4. Run the test suite.
  5. Submit a pull request.

Example:

git clone https://github.com/abolfazlrastegar/laravel-excel-exporter.git

cd laravel-excel-exporter

composer install

composer test

Security

If you discover a security vulnerability, please do not open a public issue.

Contact the maintainer directly.

License

This package is open-sourced software licensed under the MIT license.

Author

Abolfazl Rastegar

Changelog

See CHANGELOG.md for the complete changelog.

Roadmap

Planned features:

  • Multiple worksheets
  • Excel styling API
  • Header styling
  • Cell formatting
  • Conditional formatting
  • Image export
  • Multiple CSV formats
  • Advanced streaming XLSX
  • Export progress tracking
  • Queue progress events
  • Export notifications
  • S3-compatible storage
  • Chunk configuration
  • Custom writer contracts
  • Custom value transformers
  • Import support

⭐ Support the Project

If this package is useful for your Laravel projects, consider giving the repository a star on GitHub.

Thank you for using Laravel Excel Exporter.