maatwebsite/excel
Laravel Excel wraps PhpSpreadsheet to make fast, elegant Excel/CSV imports and exports in Laravel. Export collections or queries with automatic chunking, build multi-sheet files, and handle queued, large datasets with a simple API and solid docs.
Installation:
composer require maatwebsite/excel
Publish the config:
php artisan vendor:publish --provider="Maatwebsite\Excel\ExcelServiceProvider" --tag=config
First Export: Create a new export class:
php artisan make:export UsersExport --model=User
Modify the generated class (app/Exports/UsersExport.php):
public function collection()
{
return User::all();
}
Use in a controller:
use App\Exports\UsersExport;
use Maatwebsite\Excel\Facades\Excel;
public function export()
{
return Excel::download(new UsersExport, 'users.xlsx');
}
First Import: Create an import class:
php artisan make:import UsersImport
Modify the generated class (app/Imports/UsersImport.php):
public function model(array $row)
{
return new User([
'name' => $row[0],
'email' => $row[1],
]);
}
Use in a controller:
public function import(Request $request)
{
$request->validate([
'file' => 'required|file',
]);
Excel::import('UsersImport', $request->file('file'));
return back()->with('success', 'Import successful!');
}
WithHeadingRow, WithValidation, WithChunkReading, etc.) in app/Imports/ or app/Exports/config/excel.php) for customization (e.g., chunk size, disk settings, CSV encoding)make:export, make:import) for scaffoldingFrom Collections/Queries:
// app/Exports/PostsExport.php
public function collection()
{
return Post::query()->where('published', true)->get();
}
// Controller
return Excel::download(new PostsExport, 'posts.xlsx');
From Views (Blade):
// app/Exports/PostsViewExport.php
public function view()
{
return view('posts.export', ['posts' => Post::all()]);
}
<!-- resources/views/posts/export.blade.php -->
<table>
@foreach($posts as $post)
<tr>
<td>{{ $post->title }}</td>
<td>{{ $post->body }}</td>
</tr>
@endforeach
</table>
Chunked Exports (Large Datasets):
// app/Exports/UsersExport.php
use WithChunkReading;
public function chunk($result)
{
return $result->chunk(1000);
}
// Controller (queued)
return Excel::queue(new UsersExport)->download();
Basic Import:
// app/Imports/UsersImport.php
use WithHeadingRow;
public function model(array $row)
{
return new User([
'name' => $row['name'],
'email' => $row['email'],
]);
}
Validated Import:
// app/Imports/UsersImport.php
use WithValidation;
public function rules()
{
return [
'name' => 'required|string|max:255',
'email' => 'required|email',
];
}
public function customValidationRules()
{
return [
'email' => 'unique:users',
];
}
Chunked Imports (Large Files):
// app/Imports/UsersImport.php
use WithChunkReading;
public function chunk($rows)
{
foreach ($rows as $row) {
User::create([
'name' => $row[0],
'email' => $row[1],
]);
}
}
// Controller (queued)
Excel::queue(new UsersImport)->chunk(500, null, true)->process();
Upserting Data:
// app/Imports/UsersImport.php
use WithUpserts;
public function model(array $row)
{
return User::updateOrCreate(
['email' => $row['email']],
['name' => $row['name']]
);
}
Custom Styling:
// app/Exports/UsersExport.php
use WithStyles;
public function styles(Sheet $sheet)
{
$sheet->getStyle('A1')->applyFromArray([
'font' => ['bold' => true],
'alignment' => ['horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER],
]);
}
Event Handling:
// app/Imports/UsersImport.php
use BeforeImport, AfterImport;
public function beforeImport()
{
Log::info('Starting import...');
}
public function afterImport()
{
Log::info('Import completed!');
}
Queue Exports/Imports:
Use Excel::queue() for background processing with Laravel Queues.
Example:
Excel::queue(new LargeExport)->chain([
new NotifyUserJob($user),
])->dispatch();
Custom Disk Storage:
Configure temp_disk in config/excel.php to store temporary files:
'temp_disk' => 's3',
Testing:
Use the assertExportedInRaw() helper for unit tests:
public function test_export()
{
$this->assertExportedInRaw(new UsersExport, 'users.xlsx');
}
API Responses: Return Excel files with custom headers:
return Excel::download(new UsersExport, 'users.xlsx', [
'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0',
]);
Laravel Nova Integration:
Use the laravel-nova-excel package for Excel exports/imports in Nova.
Memory Limits:
WithChunkReading or queue jobs.// app/Exports/UsersExport.php
use WithChunkReading;
public function chunk($result)
{
return $result->cursor()->chunk(500);
}
Column Mapping Issues:
model(array $row) or rules().WithHeadingRow to auto-map headers:
use WithHeadingRow;
public function model(array $row)
{
return new User([
'name' => $row['name'], // Matches heading 'name'
]);
}
Validation Failures:
SkipsErrors to skip or WithValidation to halt on failure.// app/Imports/UsersImport.php
use WithValidation, SkipsErrors;
public function rules()
{
return [
'email' => 'required|email|unique:users',
];
}
Timezone Issues:
WithDateFormats:
// app/Exports/UsersExport.php
use WithDateFormats;
protected function headings(): array
{
return [
'Created At',
];
}
protected function dateFormats(): array
{
return [
'Created At' => 'Y-m-d H:i:s',
];
}
File Locking:
WithRetry or queue chunks:
Excel::queue(new UsersImport)->chunk(200, null, true)->retry(3)->process();
Special Characters:
WithEncoding:
// config/excel.php
'csv' => [
'encoding
How can I help you explore Laravel packages today?