laravel-excel-exporter maintained by abolfazrastegar

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.