Friday, May 22, 2026Today's Paper

Omni Apps

Excel Laravel Import: The Ultimate Developer's Guide
May 22, 2026 · 10 min read

Excel Laravel Import: The Ultimate Developer's Guide

Master the excel laravel import workflow. Learn basic model imports, model-less parsing, chunking for large files, and how it compares to CodeIgniter.

May 22, 2026 · 10 min read
LaravelPHP DevelopmentBackend Engineering

Managing data ingestion is a core requirement for almost any enterprise web application. When your clients or users ask to upload spreadsheet data, you need a robust, performant system. In the PHP ecosystem, the excel laravel import workflow is widely dominated by Maatwebsite's Laravel Excel package. However, setting up an import system that is both secure and fast requires more than just running a single generator command.

Whether you are managing a legacy setup using an import excel laravel 8 approach, streamlining your laravel 9 excel import configuration, or working on the latest Laravel versions, this guide provides an end-to-end blueprint. We will cover basic model-based imports, dive deep into the highly requested laravel excel import without model technique, scale your application with chunking, and briefly compare this with an import excel codeigniter setup.


1. Setting Up Excel Laravel Import: Packages and Configuration

To build a clean import system, we rely on the industry-standard maatwebsite/excel package, which acts as a powerful Laravel-flavored wrapper around phpoffice/phpspreadsheet [1]. It simplifies the complex task of parsing columns, handling files, and interacting with Eloquent.

Installation

Run the following Composer command in your terminal. This package is compatible with Laravel 8, Laravel 9, Laravel 10, and Laravel 11:

composer require maatwebsite/excel

If you are running older setups like a laravel 9 import excel environment, the package automatically registers its service providers. However, if you are working with strict configurations or manual discovery, you can add the service provider and facades manually to your config/app.php array:

'providers' => [
    // ...
    Maatwebsite\Excel\ExcelServiceProvider::class,
],

'aliases' => [
    // ...
    'Excel' => Maatwebsite\Excel\Facades\Excel::class,
],

Next, publish the configuration file to customize temporary file storage paths, default drivers, and sheet parsing behaviors:

php artisan vendor:publish --provider="Maatwebsite\Excel\ExcelServiceProvider" --tag=config

This command creates a new file at config/excel.php. Within this configuration, you can toggle settings like your temporary file path (crucial for large imports that require local disk buffering) and default cell format values.


2. Basic Model-Based Imports

The fastest way to process a spreadsheet is to map each row directly to an Eloquent model. This approach is highly efficient for simple data models like contact lists, inventory items, or system users.

Let's generate our import class using the built-in Artisan command:

php artisan make:import UsersImport --model=User

This command generates a new class inside the app/Imports directory. By implementing the ToModel and WithHeadingRow concerns, we can cleanly map spreadsheet headers directly to database fields.

The UsersImport Class

namespace App\Imports;

use App\Models\User;
use Illuminate\Support\Facades\Hash;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;

class UsersImport implements ToModel, WithHeadingRow

{
    /**
     * @param array $row
     *
     * @return \Illuminate\Database\Eloquent\Model|null
     */
    public function model(array $row)
    {
        return new User([
            'name'     => $row['name'],
            'email'    => $row['email'],
            'password' => Hash::make($row['password'] ?? 'default_password'),
        ]);
    }
}

The Controller Action

Next, we need a controller to handle the incoming HTTP file upload. This implementation works seamlessly across standard Laravel versions, ensuring high backward compatibility with older setups like import excel laravel 8 systems:

namespace App\Http\Controllers;

use App\Imports\UsersImport;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Facades\Excel;

class UserController extends Controller
{
    public function import(Request $request)
    
    {
        $request->validate([
            'excel_file' => 'required|mimes:xlsx,xls,csv|max:10240',
        ]);

        Excel::import(new UsersImport, $request->file('excel_file'));

        return back()->with('success', 'All users have been imported successfully!');
    }
}

Using the WithHeadingRow concern is a developer best practice. Instead of relying on numeric indexes (such as $row[0], $row[1]), Laravel Excel automatically converts your header row (the first row in the sheet) into slugified array keys. A spreadsheet column named "User Email" becomes readable as $row['user_email'].


3. Laravel Excel Import Without Model: The Clean Array/Collection Approach

While mapping rows directly to Eloquent models is great, real-world development is rarely that simple. Often, you need to:

  • Validate complex business logic across multiple database tables.
  • Send incoming data to an external API instead of saving it locally.
  • Format raw data prior to any database interaction.
  • Process structural metadata or run custom aggregation formulas.

For these use cases, a laravel excel import without model workflow is the ideal solution. Instead of implementing ToModel, we use ToCollection or ToArray.

Let's create an import class that processes custom transaction records without coupling to a database model:

php artisan make:import TransactionsImport

Custom TransactionsImport Class (Using ToCollection)

namespace App\Imports;

use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Http;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\WithHeadingRow;

class TransactionsImport implements ToCollection, WithHeadingRow
{
    /**
     * @param Collection $rows
     */
    public function collection(Collection $rows)
    {
        foreach ($rows as $row) {
            // 1. Calculate fees dynamically
            $grossAmount = (float) $row['amount'];
            $processingFee = $grossAmount * 0.03;
            $netAmount = $grossAmount - $processingFee;

            // 2. Format custom system logs
            info("Processing transaction for: {$row['customer_email']}");

            // 3. Dispatch to an external billing API
            $response = Http::post('https://api.billing-service.com/v1/charges', [
                'email' => $row['customer_email'],
                'amount_cents' => (int) ($netAmount * 100),
                'currency' => strtolower($row['currency'] ?? 'usd'),
            ]);

            if ($response->failed()) {
                logger()->error("Failed to sync transaction for {$row['customer_email']}");
            }
        }
    }
}

When to Use ToCollection vs ToArray?

  • ToCollection: Loads the spreadsheet rows into a standard Laravel Collection instance. This allows you to chain collection helpers like .filter(), .map(), .chunk(), and .groupBy() directly on your parsed Excel sheet.
  • ToArray: Loads the spreadsheet data into raw PHP arrays. If you are handling millions of items and want to keep memory allocation to an absolute minimum, raw arrays consume fewer system resources than heavy collection objects.

4. Scaling Up: Chunking, Batching, and Queued Imports

One of the most common mistakes when building an excel laravel import workflow is assuming your files will always be small. A 50,000-row spreadsheet will easily exhaust PHP's memory limits (memory_limit) or exceed your web server's request timeout limit, leading to fatal execution errors.

To prevent this, we must scale our import using three concepts:

  1. Batch Inserts: Reduces database round-trips by bundling inserts together.
  2. Chunk Reading: Restricts memory usage by only reading small slices of the file at once.
  3. Queued Processing: Pushes the heavy parsing operation to a background job.

Here is how to combine all three optimizations into a single robust class:

namespace App\Imports;

use App\Models\Product;
use Illuminate\Contracts\Queue\ShouldQueue;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithBatchInserts;
use Maatwebsite\Excel\Concerns\WithChunkReading;

class HeavyProductsImport implements ToModel, WithHeadingRow, WithBatchInserts, WithChunkReading, ShouldQueue
{
    /**
     * @param array $row
     *
     * @return \Illuminate\Database\Eloquent\Model|null
     */
    public function model(array $row)
    {
        return new Product([
            'sku'         => $row['sku'],
            'title'       => $row['title'],
            'price'       => $row['price'],
            'stock_count' => $row['stock'],
        ]);
    }

    /**
     * Define the batch size for database inserts.
     */
    public function batchSize(): int
    {
        return 1000;
    }

    /**
     * Define the chunk size for reading files.
     */
    public function chunkSize(): int
    {
        return 1000;
    }
}

How This Works Behind the Scenes

  • WithBatchInserts: Instead of performing 1,000 separate INSERT INTO products ... queries, Laravel Excel bundles these records into a single multi-row insert statement. This dramatically optimizes database performance.
  • WithChunkReading: Instead of loading a 50MB spreadsheet entirely into RAM, Laravel Excel reads exactly 1,000 rows at a time, frees up memory, and moves on to the next chunk.
  • ShouldQueue: Implementing this interface tells Laravel to automatically push the import tasks onto your configured queue (Redis, SQS, or Database). The user receives an immediate success response, while the background workers process the file asynchronously.

5. Advanced Validation, Row Skipping, and Formatting

When importing spreadsheets, user-generated data is often malformed. Missing fields, duplicate email addresses, or invalid date formats can easily break your database structure.

Laravel Excel integrates directly with Laravel's built-in validation engine, allowing you to validate row data and safely handle processing failures.

Let's configure custom validation rules and configure our class to skip bad rows instead of crashing entirely:

namespace App\Imports;

use App\Models\User;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithValidation;
use Maatwebsite\Excel\Concerns\SkipsOnFailure;
use Maatwebsite\Excel\Validators\Failure;
use Maatwebsite\Excel\Concerns\SkipsFailures;

class ValidatedUsersImport implements ToModel, WithHeadingRow, WithValidation, SkipsOnFailure
{
    use SkipsFailures;

    public function model(array $row)
    {
        return new User([
            'name'  => $row['name'],
            'email' => $row['email'],
        ]);
    }

    /**
     * Define row-by-row validation rules.
     */
    public function rules(): array
    {
        return [
            '*.email' => 'required|email|unique:users,email',
            '*.name'  => 'required|string|max:100',
        ];
    }
}

Handling Validation Failures in Your Controller

By utilizing the SkipsFailures trait, you can review any validation issues that occurred during import and feed them back to the user:

public function import(Request $request)
{
    $import = new ValidatedUsersImport;
    
    Excel::import($import, $request->file('excel_file'));

    if ($import->failures()->isNotEmpty()) {
        return back()->with('failures', $import->failures());
    }

    return back()->with('success', 'Import completed successfully!');
}

You can then display these custom error logs in your Blade template to show users exactly which spreadsheet row failed and why:

@if (session()->has('failures'))
    <div class="alert alert-danger">
        <h4>The following errors occurred during processing:</h4>
        <ul>
            @foreach (session()->get('failures') as $validationFailure)
                <li>
                    Row #{{ $validationFailure->row() }}: 
                    {{ implode(', ', $validationFailure->errors()) }}
                </li>
            @endforeach
        </ul>
    </div>
@endif

6. Framework Alternatives: Excel Import in CodeIgniter 4

Not every backend development stack utilizes Laravel. If you are developing a project in a sister PHP framework and searching for import excel codeigniter or import excel codeigniter 4 options, the system is structured slightly differently.

CodeIgniter 4 does not feature a dedicated framework wrapper with the scale of Maatwebsite Excel. Instead, CodeIgniter developers interact directly with PhpSpreadsheet [1]. Here is a basic structural overview of how to process an Excel import within a CodeIgniter 4 Controller:

Step 1: Install PhpSpreadsheet in your CI4 App

composer require phpoffice/phpspreadsheet

Step 2: CodeIgniter 4 Controller Logic

namespace App\Controllers;

use CodeIgniter\Controller;
use PhpOffice\PhpSpreadsheet\IOFactory;

class ExcelImport extends Controller
{
    public function import()
    {
        $file = $this->request->getFile('excel_file');

        if (!$file->isValid()) {
            return redirect()->back()->with('error', $file->getErrorString());
        }

        // Load the spreadsheet from temporary path
        $spreadsheet = IOFactory::load($file->getTempName());
        $sheetData = $spreadsheet->getActiveSheet()->toArray(null, true, true, true);

        $db = \Config\Database::connect();
        $builder = $db->table('users');

        $insertedRows = 0;

        foreach ($sheetData as $index => $row) {
            // Skip the first row (the column headers)
            if ($index === 1) {
                continue;
            }

            $data = [
                'name'  => $row['A'], // Map column A to Name
                'email' => $row['B'], // Map column B to Email
            ];

            $builder->insert($data);
            $insertedRows++;
        }

        return redirect()->back()->with('success', "Successfully imported {$insertedRows} records.");
    }
}

While CodeIgniter 4 lacks the automated facades, queues, and model mapping abstractions found in Laravel, utilizing PhpSpreadsheet directly provides highly robust spreadsheet-parsing performance for non-Laravel codebases.


7. Troubleshooting & FAQ

How do I import Excel without a model in Laravel?

To run an laravel excel import without model, implement the Maatwebsite\Excel\Concerns\ToCollection or Maatwebsite\Excel\Concerns\ToArray interfaces instead of ToModel. This will output raw rows as a collection or raw array inside your class, letting you execute custom operations, invoke external APIs, or execute raw database inserts.

Why are my Excel date values importing as large numbers (e.g., 44211)?

Excel stores dates internally as serial numbers representing the number of days elapsed since January 1, 1900. To convert this serial value back to a standard PHP DateTime object, utilize PhpSpreadsheet's built-in helper:

$dateTime = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row['date_column']);
$formattedDate = $dateTime->format('Y-m-d');

Does this guide support Laravel 9 excel import files?

Yes. The core architecture of Maatwebsite Excel remains largely identical across Laravel 8, 9, 10, and 11. The syntax, queue interfaces, and validation systems covered in this tutorial are fully backward-compatible with any laravel 9 excel import configuration.

How can I limit memory usage for massive spreadsheet imports?

Always combine WithChunkReading and WithBatchInserts to prevent PHP memory exhaustion. Additionally, run your imports in the background by implementing the ShouldQueue interface, routing the heavy processing work directly to your system queue workers.


Conclusion

Building an excel laravel import pipeline is relatively simple using the Maatwebsite Excel package. However, scaling that pipeline requires choosing the right architecture. If your application requires basic table mapping, a traditional ToModel approach works beautifully. For complex database tasks or external syncs, use the laravel excel import without model (ToCollection) approach to preserve clean boundaries.

By leveraging batch inserts, chunk reading, row validation, and queues, you can process enterprise-scale spreadsheets of any file size without taxing your server. Optimize your import systems today using these production-ready practices!

Related articles
How to Export Excel in Laravel: The Ultimate High-Performance Guide
How to Export Excel in Laravel: The Ultimate High-Performance Guide
Learn how to export Excel in Laravel 8 through modern versions. Master high-performance chunking, styled Blade views, imports, and queue-based background tasks.
May 22, 2026 · 11 min read
Read →
The Ultimate Guide to Laravel 8 Excel Import: Step-by-Step
The Ultimate Guide to Laravel 8 Excel Import: Step-by-Step
Master Laravel 8 excel import using Maatwebsite Excel. Learn to handle massive datasets with chunk reading, queue imports, custom validation, and skip errors.
May 21, 2026 · 12 min read
Read →
Excel 365 Import CSV: The Ultimate Guide to Perfect Data Formatting
Excel 365 Import CSV: The Ultimate Guide to Perfect Data Formatting
Master the Excel 365 import csv process. Learn how to preserve leading zeros, fix broken text encoding, and automate CSV imports using Power Query.
May 22, 2026 · 14 min read
Read →
Excel VBA CSV Export: The Ultimate Automated Guide
Excel VBA CSV Export: The Ultimate Automated Guide
Master Excel VBA CSV export procedures. Learn to convert Excel to CSV, import files with leading zeros, handle special characters, and write VB.NET solutions.
May 22, 2026 · 12 min read
Read →
How to Convert Photoshop PDF to JPG (and JPG to PDF)
How to Convert Photoshop PDF to JPG (and JPG to PDF)
Learn to convert a Photoshop pdf to jpg with perfect image quality. Master step-by-step conversion, batch pages, and how to convert jpg to pdf photoshop.
May 22, 2026 · 14 min read
Read →
How to Check If Plagiarized: The Complete Originality Guide
How to Check If Plagiarized: The Complete Originality Guide
Want to check if plagiarized text is hiding in your work? Use this master guide to scan your writing, identify copied matches, and ensure 100% unique prose.
May 22, 2026 · 10 min read
Read →
Convert PSI to Meter: The Complete Pressure to Head Guide
Convert PSI to Meter: The Complete Pressure to Head Guide
Need to convert PSI to meter head? Master the formulas, specific gravity adjustments, conversion tables, and find out how to link pressure to tank volume.
May 22, 2026 · 15 min read
Read →
Mastering Your Weight Goals with a BMI TDEE Calculator
Mastering Your Weight Goals with a BMI TDEE Calculator
Unlock your metabolic potential. Use a BMI TDEE calculator to strategically track health status, determine maintenance calories, and lose fat safely.
May 22, 2026 · 13 min read
Read →
namemesh com domain: Best Modern Alternatives to Try
namemesh com domain: Best Modern Alternatives to Try
Looking for the namemesh com domain tool? Discover why the legendary domain generator disappeared and find the best modern alternatives to claim your brand.
May 22, 2026 · 11 min read
Read →
How to Extract an SVG Path from an Image: The Ultimate Developer & Designer Guide
How to Extract an SVG Path from an Image: The Ultimate Developer & Designer Guide
Learn how to extract a clean SVG path from an image. Discover online generators, design tool workflows (Figma, Illustrator), and programmatic code solutions.
May 22, 2026 · 13 min read
Read →
Related articles
Related articles