Excel Import plugin screenshot
Dark mode ready
Multilingual support
Supports v5.x

Excel Import

A powerful and flexible Excel import package for Filament that extends the native import functionality with enhanced features, better error handling, and comprehensive validation.

Tags: Action Form Field Panels Developer Tool
Supported versions:
3.x
Hayder Hatem avatar Author: Hayder Hatem

Documentation

A powerful Excel import package for Filament that provides seamless Excel file import functionality with automatic column mapping and memory-efficient processing.

#Installation

You can install the package via composer:

composer require hayderhatem/filament-excel-import

#Features

  • 📊 Excel & CSV Import: Support for .xlsx, .xls, .csv and other spreadsheet formats
  • 🔄 Drop-in Replacement: Compatible with Filament's existing CanImportRecords trait
  • 🗂️ Multi-Sheet Support: Import from specific sheets in Excel workbooks
  • 🎯 Smart Column Mapping: Automatic header detection and column mapping
  • 🚀 Memory Efficient: Handles large files without memory exhaustion
  • 🔁 Streaming Import: Automatic streaming for large files (configurable)
  • 📝 Custom Import Options: Add additional form fields to import modal
  • 🌐 Full Internationalization: Complete translation support with RTL for Arabic
  • ⚠️ Error Handling: User-friendly error messages and failed rows export
  • 🎨 Easy Configuration: Minimal setup required

#Usage

#Basic Setup

Replace Filament's CanImportRecords trait with CanImportExcelRecords in your resource:

<?php

namespace App\Filament\Resources;

use App\Filament\Imports\UserImporter;
use App\Models\User;
use Filament\Resources\Resource;
use HayderHatem\FilamentExcelImport\Actions\FullImportAction;
use HayderHatem\FilamentExcelImport\Actions\Concerns\CanImportExcelRecords;

class UserResource extends Resource
{
    protected static ?string $model = User::class;

    public static function getHeaderActions(): array
    {
        return [
            FullImportAction::make()
                ->importer(UserImporter::class),
        ];
    }
}

#Configuration Options

The package supports all of Filament's original import options plus additional Excel-specific features:

FullImportAction::make()
    ->importer(UserImporter::class)
    // Standard Filament options
    ->chunkSize(1000)
    ->maxRows(10000)
    ->headerOffset(0) // Row number where headers are located (0-based)
    ->job(CustomImportJob::class) // Custom job class
    // Excel-specific options
    ->activeSheet(0) // Which Excel sheet to import (0-based)
    ->useStreaming(true) // Force streaming mode
    ->streamingThreshold(10 * 1024 * 1024) // 10MB threshold for auto-streaming

#Multi-Sheet Excel Files

When importing Excel files with multiple sheets, users can select which sheet to import:

FullImportAction::make()
    ->importer(UserImporter::class)
    ->activeSheet(0) // Default to first sheet

The import modal will automatically show a sheet selector dropdown if multiple sheets are detected.

#Additional Form Components

You can add custom form fields to the import modal:

use Filament\Forms\Components\Select;
use Filament\Forms\Components\Toggle;

FullImportAction::make()
    ->importer(UserImporter::class)
    ->additionalFormComponents([
        Select::make('department_id')
            ->label('Default Department')
            ->options(Department::pluck('name', 'id'))
            ->required(),
        
        Toggle::make('send_welcome_email')
            ->label('Send Welcome Email')
            ->default(true),
    ])

Access additional form data in your importer:

use HayderHatem\FilamentExcelImport\Traits\CanAccessAdditionalFormData;

class UserImporter extends Importer
{
    use CanAccessAdditionalFormData;
    
    public function import(array $data, array $map, array $options = []): void
    {
        $departmentId = $this->getAdditionalFormValue('department_id');
        $sendEmail = $this->getAdditionalFormValue('send_welcome_email', false);
        
        // Your import logic...
    }
}

#Memory Optimization & Streaming

#Automatic Streaming

The package automatically detects large files and switches to streaming mode to prevent memory exhaustion:

// Files larger than 10MB (default) will automatically use streaming
FullImportAction::make()
    ->importer(UserImporter::class)
    ->streamingThreshold(5 * 1024 * 1024) // Custom 5MB threshold

#Manual Streaming Control

Force streaming mode on or off:

FullImportAction::make()
    ->importer(UserImporter::class)
    ->useStreaming(true) // Always use streaming
    // or
    ->useStreaming(false) // Never use streaming
    // or
    ->useStreaming(null) // Auto-detect (default)

#Memory Usage Comparison

File Size Standard Import Streaming Import
1MB ~10MB RAM ~5MB RAM
100MB Memory Error ~5MB RAM
1GB Memory Error ~5MB RAM

#Advanced Configuration

#Custom Job

You can use your own import job class:

use HayderHatem\FilamentExcelImport\Actions\Imports\Jobs\ImportExcel;

class CustomImportJob extends ImportExcel
{
    public function handle(): void
    {
        // Custom pre-processing
        
        parent::handle();
        
        // Custom post-processing
    }
}

// Use in your action
FullImportAction::make()
    ->importer(UserImporter::class)
    ->job(CustomImportJob::class)

#Error Handling

The package provides user-friendly error messages for common database errors:

// Errors are automatically translated and user-friendly
// - "Email field is required" instead of SQL constraint errors  
// - "Email already exists" instead of unique constraint violations
// - "Invalid department reference" instead of foreign key errors

#Custom Error Messages

Add custom error message translations:

// resources/lang/en/filament-excel-import.php
return [
    'import' => [
        'errors' => [
            'field_required' => 'The :field field is required.',
            'field_exists' => 'The :field already exists.',
            'invalid_reference' => 'Invalid reference to :table.',
        ]
    ]
];

#File Support

#Supported Formats

  • Excel: .xlsx, .xls, .xlsm, .xltx, .xltm
  • CSV: .csv, .txt
  • All formats supported by PhpSpreadsheet

#File Upload Behavior

  • Small files: Full preview with dropdown column mapping
  • Large files: Header-only reading for memory efficiency
  • Very large files: Manual text input mapping
  • Any size: Import processing always works via streaming

#API Compatibility

The package is a drop-in replacement for Filament's CanImportRecords trait:

Filament Method Supported Notes
importer() Fully compatible
job() Fully compatible
chunkSize() Fully compatible
maxRows() Fully compatible
headerOffset() Fully compatible
options() Fully compatible
fileValidationRules() Enhanced for Excel

#Additional Methods

Method Description
useStreaming(bool|null) Control streaming mode
streamingThreshold(int) Set auto-streaming threshold
activeSheet(int) Set Excel sheet to import
additionalFormComponents(array) Add custom form fields

#Migration from CanImportRecords

Migrating from Filament's built-in import is simple:

#Step 1: Update the Trait

// Before
use Filament\Actions\Concerns\CanImportRecords;

// After  
use HayderHatem\FilamentExcelImport\Actions\Concerns\CanImportExcelRecords;

#Step 2: No Other Changes Required

All your existing code will work exactly the same! The package is designed as a drop-in replacement.

#Step 3: Optional Enhancements

Take advantage of new features:

FullImportAction::make()
    ->importer(UserImporter::class)
    // Your existing configuration works as-is
    ->chunkSize(500)
    ->maxRows(5000)
    // Add new Excel features
    ->activeSheet(0)
    ->useStreaming(true)

#Testing

The package includes comprehensive tests:

# Run all tests
composer test

# Run with coverage
composer test-coverage

# Run package test runner
php test-runner.php

#Requirements

  • PHP 8.1+
  • Laravel 10+
  • Filament 3+
  • PhpSpreadsheet (automatically installed)

#Contributing

Please see CONTRIBUTING for details.

#Security

If you discover any security-related issues, please email the maintainer instead of using the issue tracker.

#Credits

#License

The MIT License (MIT). Please see License File for more information.