Importing Excel Sheets in Laravel 12: A Complete Step-by-Step Guide

Author

Kritim Yantra

Apr 17, 2025

Importing Excel Sheets in Laravel 12: A Complete Step-by-Step Guide

๐Ÿš€ 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.


๐Ÿงฐ Prerequisites

Before diving in, ensure the following are ready:

  • Laravel 12 installed
  • Composer installed
  • Basic Laravel MVC knowledge
  • Database configured in .env

๐Ÿ“ฆ Choosing the Best Package

Weโ€™ll use Maatwebsite/Laravel-Excel โ€“ the most popular and feature-rich package for Excel/CSV operations in Laravel.

โœ… Why use Maatwebsite/Laravel-Excel?

  • Simple import/export APIs
  • Efficient chunk reading for large files
  • Queue support for async processing
  • Extensive validation & formatting options
  • Great documentation & community

๐Ÿ›  Step 1: Install the Package

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.


๐Ÿงฉ Step 2: Create an Import Class

Use Artisan to generate an import class:

php artisan make:import ProductsImport --model=Product

Sample Import Class

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],
        ]);
    }
}

๐ŸŽฎ Step 3: Build the Import Controller

Generate a controller:

php artisan make:controller ImportController

Import Logic

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());
        }
    }
}

๐Ÿ–ผ Step 4: Create the Blade View

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

๐Ÿ” Step 5: Define Routes

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');

โš™๏ธ Step 6: Advanced Features

1. Handling Headers in Excel

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'],
        ]);
    }
}

2. Validation Rules

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.',
        ];
    }
}

3. Batch Inserts with 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],
            ]);
        }
    }
}

4. Queueing for Large Files

use Maatwebsite\Excel\Concerns\ShouldQueue;

class ProductsImport implements ToModel, ShouldQueue
{
    // No extra logic needed, Laravel handles this
}
Excel::queueImport(new ProductsImport, $file);

๐Ÿ” Step 7: Update or Sync Records

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],
        ]);
    }
}

๐Ÿ“„ Step 8: Import from Multiple Sheets

use Maatwebsite\Excel\Concerns\WithMultipleSheets;

class ProductsImport implements WithMultipleSheets
{
    public function sheets(): array
    {
        return [
            'Products'   => new ProductsSheetImport(),
            'Categories' => new CategoriesSheetImport(),
        ];
    }
}

๐Ÿงช Step 9: Write Automated Tests

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');
}

๐Ÿš€ Performance Optimization Tips

โœ… Chunk Reading

use Maatwebsite\Excel\Concerns\WithChunkReading;

class ProductsImport implements ToModel, WithChunkReading
{
    public function chunkSize(): int
    {
        return 1000;
    }
}

โœ… Memory Management

Update config/excel.php:

'imports' => [
    'read_only' => true,
    'ignore_empty' => true,
],

๐Ÿงฏ Common Errors & Fixes

๐Ÿง  Memory Limit Exhausted

  • Use chunking and queueing
  • Increase memory_limit in php.ini

๐Ÿง  Date Conversion Issues

use PhpOffice\PhpSpreadsheet\Shared\Date;

'date' => Date::excelToDateTimeObject($row[1]),

๐Ÿง  Mapping Errors

Use dd($row) inside model() to debug structure.


๐Ÿ“˜ Conclusion

By now, you've mastered how to:

  • Install Laravel Excel
  • Create import logic
  • Validate and optimize
  • Handle large and multi-sheet files
  • Automate and test the import process

With this, you're fully equipped to handle professional-grade Excel import functionality in your Laravel 12 application. โœ…

Tags

Comments

No comments yet. Be the first to comment!

Please log in to post a comment:

Sign in with Google

Related Posts