hayderhatem/filament-excel-import

Filament Excel import trait for Laravel
12,324 27
Install
composer require hayderhatem/filament-excel-import
Latest Version:v4.0.0
PHP:^8.1
License:MIT
Last Updated:Jul 30, 2025
Links: GitHub  ·  Packagist
Maintainer: HayderHatem

Filament Excel Import

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.

Related Packages

doctrine/dbal

Powerful PHP database abstraction layer (DBAL) with many features for database s...

631,580,251 9,707
laravel/framework

The Laravel Framework.

580,311,802 34,925
laravel/tinker

Powerful REPL for the Laravel framework.

489,754,436 7,444
laravel/serializable-closure

Laravel Serializable Closure provides an easy and secure way to serialize closur...

404,034,618 608
nunomaduro/collision

Cli error handling for console/command-line PHP applications.

387,976,821 4,658