abolfazrastegar / laravel-excel-exporter
A powerful and flexible Excel/CSV exporter for Laravel applications.
Package info
github.com/abolfazlrastegar/laravel-excel-exporter
pkg:composer/abolfazrastegar/laravel-excel-exporter
Requires
- php: ^8.2
- illuminate/support: ^10.0|^11.0|^12.0|^13.0
- phpoffice/phpspreadsheet: ^5.9
Requires (Dev)
- phpunit/phpunit: ^10.0|^11.0|^12.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Laravel Excel Exporter
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.
- Fork the repository.
- Create a feature branch.
- Add tests for your changes.
- Run the test suite.
- 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.
