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. โ
No comments yet. Be the first to comment!
Please log in to post a comment:
Sign in with Google