maatwebsite/excel
Laravel Excel is a Laravel wrapper around PhpSpreadsheet for fast, elegant Excel/CSV exports and imports. Export collections or queries with automatic chunking for performance, generate downloadable files, and process imports cleanly in your app.
Installation:
composer require maatwebsite/excel
Publish config:
php artisan vendor:publish --provider="Maatwebsite\Excel\ExcelServiceProvider" --tag=config
First Export (Collection):
use Maatwebsite\Excel\Facades\Excel;
use App\Exports\UsersExport;
// In a controller
return Excel::download(new UsersExport, 'users.xlsx');
First Import (CSV/Excel):
use App\Imports\UsersImport;
// In a controller
$import = new UsersImport;
$import->import(request()->file('file'));
Key Files to Review:
config/excel.php (configurations, chunk sizes, etc.)app/Exports/ (export classes)app/Imports/ (import classes)routes/web.php (for testing endpoints)From Eloquent Query:
use Maatwebsite\Excel\Concerns\FromQuery;
class UsersExport implements FromQuery
{
public function query()
{
return User::query()->where('active', 1);
}
}
From Collection:
use Maatwebsite\Excel\Concerns\FromCollection;
class UsersExport implements FromCollection
{
public function collection()
{
return User::active()->get();
}
}
From View (Blade):
use Maatwebsite\Excel\Concerns\FromView;
class UsersExport implements FromView
{
public function view(): string
{
return 'users.table';
}
}
Customizing Headers/Columns:
use Maatwebsite\Excel\Concerns\WithHeadings;
class UsersExport implements WithHeadings
{
public function headings(): array
{
return [
'ID', 'Name', 'Email', 'Created At'
];
}
}
Chunking for Large Exports:
use Maatwebsite\Excel\Concerns\WithChunkReading;
class UsersExport implements WithChunkReading
{
public function chunkSize(): int
{
return 1000; // Process 1000 rows at a time
}
}
Queued Exports (Background Jobs):
use Maatwebsite\Excel\Concerns\WithQueueable;
class UsersExport implements WithQueueable
{
public function queueable(): array
{
return ['queue' => 'exports'];
}
}
Basic Import:
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
class UsersImport implements ToModel, WithHeadingRow
{
public function model(array $row)
{
return new User([
'name' => $row['name'],
'email' => $row['email']
]);
}
}
Validation During Import:
use Maatwebsite\Excel\Concerns\WithValidation;
class UsersImport implements WithValidation
{
public function rules(): array
{
return [
'name' => 'required|string|max:255',
'email' => 'required|email'
];
}
}
Chunked Imports (Large Files):
use Maatwebsite\Excel\Concerns\WithChunkReading;
class UsersImport implements WithChunkReading
{
public function chunkSize(): int
{
return 500;
}
}
Queued Imports:
use Maatwebsite\Excel\Concerns\WithQueueable;
class UsersImport implements WithQueueable
{
public function queueable(): array
{
return ['queue' => 'imports'];
}
}
Handling Failures:
use Maatwebsite\Excel\Concerns\WithFailuresTable;
class UsersImport implements WithFailuresTable
{
public function failuresTable(): string
{
return 'user_import_failures';
}
}
Dynamic Filters:
use Maatwebsite\Excel\Concerns\WithCustomStartCell;
class UsersExport implements WithCustomStartCell
{
public function startCell(): string
{
return 'A2'; // Skip header row
}
}
Styling Exports:
use Maatwebsite\Excel\Concerns\WithStyles;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
class UsersExport implements WithStyles
{
public function styles(Worksheet $sheet)
{
return [
// Style the first row as bold text
1 => ['font' => ['bold' => true]],
];
}
}
Custom File Naming:
use Maatwebsite\Excel\Concerns\WithCustomName;
class UsersExport implements WithCustomName
{
public function filename(): string
{
return 'users-' . now()->format('Y-m-d') . '.xlsx';
}
}
API Responses:
return Excel::download(new UsersExport)
->setResponseHeader('Content-Disposition', 'attachment; filename="custom-name.xlsx"');
Memory Limits:
WithChunkReading and queue jobs for background processing.chunk_size in config/excel.php (default: 750).Column Mismatches:
headings() in exports match the actual data columns to avoid misaligned data.WithHeadingRow in imports to skip header rows.Queued Jobs:
database queue driver or a supported queue (e.g., Redis).File Handling:
handleFailure() in imports to manually clean up.Validation Errors:
failures table by default. Clear it manually or implement WithFailuresTable to customize.Time Zone Issues:
config/excel.php has the correct timezone setting to avoid date/time discrepancies.Special Characters:
*, ?, /). Sanitize data before export.Log Chunk Progress:
use Maatwebsite\Excel\Concerns\WithEvents;
class UsersImport implements WithEvents
{
public function registerEvents(): array
{
return [
'chunk.started' => function () {
\Log::info('Chunk started');
},
'chunk.finished' => function () {
\Log::info('Chunk finished');
},
];
}
}
Inspect Raw Data:
use Maatwebsite\Excel\Concerns\WithCustomCsvSettings;
class UsersImport implements WithCustomCsvSettings
{
public function csvSettings(): array
{
return [
'input_encoding' => 'UTF-8',
'output_encoding' => 'UTF-8',
'delimiter' => ',',
'enclosure' => '"',
'line_ending' => "\n",
'use_bom' => false,
'include_path' => true,
'read_data_only' => false, // Set to true to debug raw data
];
}
}
Test with Small Files:
WithLimit to test imports with a subset of data:
use Maatwebsite\Excel\Concerns\WithLimit;
class UsersImport implements WithLimit
{
public function limit(): int
{
return 10; // Test with first 10 rows
}
}
Check PhpSpreadsheet Cache:
php artisan cache:clear
config/excel.php:
'cache' => [
'driver' => 'file',
'path' => storage_path('framework/cache/data'),
],
WithCustomFooter):
namespace App\Concerns;
use Maatwebsite\Excel\
How can I help you explore Laravel packages today?