Kritim Yantra
Apr 17, 2025
๐ Introduction
Need to import Excel files into your Laravel 12 application? Whether it's bulk product uploads, user lists, or financial data, this feature is crucial for many real-world applications.
In this guide, you'll learn how to import Excel files using the Laravel-Excel package by Maatwebsite, from installation to advanced use cases like chunking, validation, and queueing.
Before diving in, ensure the following are ready:
.env
Weโll use Maatwebsite/Laravel-Excel โ the most popular and feature-rich package for Excel/CSV operations in Laravel.
Install the package via Composer:
composer require maatwebsite/excel
Then publish the configuration:
php artisan vendor:publish --provider="Maatwebsite\Excel\ExcelServiceProvider" --tag=config
This creates a config file at config/excel.php
.
Use Artisan to generate an import class:
php artisan make:import ProductsImport --model=Product
namespace App\Imports;
use App\Models\Product;
use Maatwebsite\Excel\Concerns\ToModel;
class ProductsImport implements ToModel
{
public function model(array $row)
{
return new Product([
'name' => $row[0],
'price' => $row[1],
]);
}
}
Generate a controller:
php artisan make:controller ImportController
namespace App\Http\Controllers;
use App\Imports\ProductsImport;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Facades\Excel;
class ImportController extends Controller
{
public function showImportForm()
{
return view('import');
}
public function import(Request $request)
{
$request->validate([
'file' => 'required|mimes:xlsx,xls,csv|max:2048',
]);
try {
Excel::import(new ProductsImport, $request->file('file'));
return back()->with('success', 'Products imported successfully!');
} catch (\Exception $e) {
return back()->with('error', 'Error importing file: ' . $e->getMessage());
}
}
}
File: resources/views/import.blade.php
@extends('layouts.app')
@section('content')
<div class="container">
<h2>Import Products</h2>
@if(session('success'))
<div class="alert alert-success">{{ session('success') }}</div>
@endif
@if(session('error'))
<div class="alert alert-danger">{{ session('error') }}</div>
@endif
<form action="{{ route('import.process') }}" method="POST" enctype="multipart/form-data">
@csrf
<div class="form-group">
<label for="file">Choose Excel File</label>
<input type="file" name="file" id="file" class="form-control" required>
<small class="form-text text-muted">Accepted: .xlsx, .xls, .csv | Max: 2MB</small>
</div>
<button type="submit" class="btn btn-primary mt-3">Import</button>
</form>
</div>
@endsection
In routes/web.php
:
use App\Http\Controllers\ImportController;
Route::get('/import', [ImportController::class, 'showImportForm'])->name('import.form');
Route::post('/import', [ImportController::class, 'import'])->name('import.process');
If the file has column headers:
use Maatwebsite\Excel\Concerns\WithHeadingRow;
class ProductsImport implements ToModel, WithHeadingRow
{
public function model(array $row)
{
return new Product([
'name' => $row['product_name'],
'price' => $row['price'],
]);
}
}
use Maatwebsite\Excel\Concerns\WithValidation;
class ProductsImport implements ToModel, WithValidation
{
public function rules(): array
{
return [
'0' => 'required|string',
'1' => 'required|numeric',
];
}
public function customValidationMessages()
{
return [
'0.required' => 'Product name is required.',
'1.numeric' => 'Price must be a number.',
];
}
}
ToCollection
use Maatwebsite\Excel\Concerns\ToCollection;
use Illuminate\Support\Collection;
class ProductsImport implements ToCollection
{
public function collection(Collection $rows)
{
foreach ($rows as $row) {
Product::create([
'name' => $row[0],
'price' => $row[1],
]);
}
}
}
use Maatwebsite\Excel\Concerns\ShouldQueue;
class ProductsImport implements ToModel, ShouldQueue
{
// No extra logic needed, Laravel handles this
}
Excel::queueImport(new ProductsImport, $file);
To update existing records:
use Maatwebsite\Excel\Concerns\WithUpserts;
class ProductsImport implements ToModel, WithUpserts
{
public function uniqueBy()
{
return 'sku';
}
public function model(array $row)
{
return new Product([
'sku' => $row[0],
'name' => $row[1],
'price' => $row[2],
]);
}
}
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
class ProductsImport implements WithMultipleSheets
{
public function sheets(): array
{
return [
'Products' => new ProductsSheetImport(),
'Categories' => new CategoriesSheetImport(),
];
}
}
php artisan make:test ImportTest
use Illuminate\Http\UploadedFile;
use Maatwebsite\Excel\Facades\Excel;
public function test_import_page_loads()
{
$this->get('/import')->assertStatus(200);
}
public function test_valid_excel_file_can_be_imported()
{
Excel::fake();
$file = UploadedFile::fake()->create('products.xlsx');
$this->post('/import', ['file' => $file]);
Excel::assertImported('products.xlsx');
}
public function test_invalid_file_is_rejected()
{
$file = UploadedFile::fake()->create('products.pdf');
$this->post('/import', ['file' => $file])
->assertSessionHasErrors('file');
}
use Maatwebsite\Excel\Concerns\WithChunkReading;
class ProductsImport implements ToModel, WithChunkReading
{
public function chunkSize(): int
{
return 1000;
}
}
Update config/excel.php
:
'imports' => [
'read_only' => true,
'ignore_empty' => true,
],
memory_limit
in php.ini
use PhpOffice\PhpSpreadsheet\Shared\Date;
'date' => Date::excelToDateTimeObject($row[1]),
Use dd($row)
inside model()
to debug structure.
By now, you've mastered how to:
With this, you're fully equipped to handle professional-grade Excel import functionality in your Laravel 12 application. โ
Transform from beginner to Laravel expert with our personalized Coaching Class starting June 21, 2025. Limited enrollment ensures focused attention.
1-hour personalized coaching
Build portfolio applications
Industry-standard techniques
Interview prep & job guidance
Complete your application to secure your spot
Thank you for your interest in our Laravel mentorship program. We'll contact you within 24 hours with next steps.
No comments yet. Be the first to comment!
Please log in to post a comment:
Sign in with Google