Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Export Laravel Package

alperenersoy/filament-export

Filament Export lets you add Excel and CSV export buttons to Filament resources and tables. Customize columns, formatting, and file names, and filter which records are exported, so admins can download data straight from the panel.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and publish

composer require alperenersoy/filament-export

php artisan vendor:publish --tag="filament-export-config"
php artisan vendor:publish --tag="filament-export-views"   # only if printing/custom markup matters

The package needs a Filament panel already set up; ext-zip is required if you enable XLSX output (PhpSpreadsheet is pulled in for spreadsheet writing). Check composer show alperenersoy/filament-export against your Filament major — the action namespaces and registration style differ between Filament 2, 3, and 4, so pin the package version that matches your panel.

First use case: a filtered CSV export on a resource

Add the header action to any resource table. It reads the table's current query, so search, filters, and sorting are respected:

use AlperenErsoy\FilamentExport\Actions\FilamentExportHeaderAction;
use AlperenErsoy\FilamentExport\Actions\FilamentExportBulkAction;

public static function table(Table $table): Table
{
    return $table
        ->columns([
            TextColumn::make('name')->searchable()->sortable(),
            TextColumn::make('email')->searchable(),
            TextColumn::make('created_at')->dateTime(),
        ])
        ->headerActions([
            FilamentExportHeaderAction::make('export')
                ->label('Export')
                ->fileName('users-' . now()->format('Y-m-d'))
                ->formats(['csv', 'xlsx']),
        ])
        ->bulkActions([
            FilamentExportBulkAction::make('export')
                ->label('Export selected'),
        ]);
}

Run php artisan config:clear after publishing the config, then hit the button. The modal lets the user pick format and columns, and offers Export/Print.

Where to look first

  • config/filament-export.php — defaults for format, CSV delimiter/enclosure/BOM, date/time formats, preview behaviour, page orientation.
  • The README's customization section for the fluent API.
  • vendor/alperenersoy/filament-export/src/Actions/FilamentExportHeaderAction.php — the authoritative list of ->methods() for the version you actually installed. The API has shifted across Filament majors; the source is faster than guessing.

Implementation Patterns

Header vs. bulk action. Use FilamentExportHeaderAction when the user should export "what I'm currently looking at" (respects table filters/search). Use FilamentExportBulkAction when they should export exactly the checked rows. The bulk action exports the selected records only, so its scope follows your table's selection config (selectCurrentPageOnly, etc.) — document that for users who expect "select all across pages".

Curation beats configuration. The column picker is populated from the table columns. Shape the export by shaping the table: use TextColumn::make('status')->getStateUsing(fn ($record) => $record->status->label()) so enums export as human labels instead of raw values, and format dates via the action's dateFormat() / timeFormat() rather than in every accessor.

Additional/computed columns. For values that aren't real table columns (full address, balance, related counts), define them as additional columns on the action. This keeps the table clean while still giving finance/ops the extra fields. Verify the exact signature in your installed version — the additional-columns API is one of the parts that changed between majors.

Print instead of PDF. The print path renders an HTML table in a print-friendly view and hands off to the browser's print dialog. That's usually the right call internally: no PDF binary, no font headaches, and users can "Save as PDF" if they need a file. Publish the views to add a logo, letterhead, footer, or company header, and set page orientation to landscape for wide tables.

Reusable action factory. For apps with a dozen resources, don't copy the same five chained calls. Add a small helper:

// app/Filament/Support/ExportActions.php
public static function make(string $name, string $file): FilamentExportHeaderAction
{
    return FilamentExportHeaderAction::make($name)
        ->fileName($file)
        ->formats(['csv', 'xlsx'])
        ->dateFormat('d/m/Y')
        ->timeFormat('H:i');
}

Authorization. Wrap the action with ->visible(fn () => auth()->user()->can('export', User::class)) or a policy check. The action exports whatever columns the table exposes, so visibility is the only thing standing between a curious user and a CSV of every column you left on the table.

Large datasets. Prefer CSV over XLSX once you're past a few tens of thousands of rows — XLSX via PhpSpreadsheet is memory-hungry and synchronous. For genuinely large exports, constrain the action's query or move the export to a queued job; this package generates the file on the request, not in a worker.

Audit trail. There's no event system to hook, so if you need "who exported what", wrap the export behind your own action or log inside a custom action class that calls the same export service. Treat exported files as sensitive data and avoid leaving them in public storage.

Gotchas and Tips

CSV formula injection. Values beginning with =, +, -, or @ can be interpreted as formulas when opened in Excel. If users can type into fields that end up in an export, sanitize those values (prefix with a single quote or a tab) in an accessor before they reach the CSV writer.

Excel and non-ASCII characters. If accented or Turkish characters look garbled when opening the CSV in Excel, enable the BOM option in config/filament-export.php (csv_bom / equivalent) or set the delimiter to ; for locales where comma is the decimal separator. Both are config-level, not per-action.

Dates are not magically formatted. dateFormat() / timeFormat() apply to values the package recognizes as dates (Carbon casts, date columns). Raw strings from a selectRaw or a joined column pass through untouched — format them at the accessor level.

Relation and joined columns. Columns backed by relationships may not resolve in the export query the way they do in the table row. If a relationship column exports blank, add an accessor on the model or a getStateUsing on the column, and confirm the export query actually selects the needed data.

Preview route and popup blockers. If preview is enabled, the export first renders a preview page with download/print controls; print opens a browser print context. Users with aggressive popup blockers will report "nothing happens" — that's usually the browser, not the package. directDownload()/disablePreview() is the fix for teams that just want the file.

Config cache. After changing config/filament-export.php in production, run php artisan config:cache (or config:clear locally). A stale cached config is the most common reason a changed delimiter or default format appears to be ignored.

Filenames. Keep fileName() free of slashes and characters that break Content-Disposition; the package appends the extension based on the chosen format. Non-ASCII filenames can behave differently across browsers and proxies.

Sensitive columns. The column picker lists the table's columns. Password hashes, tokens, internal notes, and PII should never be table columns in the first place, but double-check before shipping an export button to a broad audience.

Version drift. The package supports multiple Filament majors, and header/bulk action registration changed in Filament 4 (actions moved under Filament\Actions). If the action doesn't appear, confirm the namespace matches your Filament version and that the action is returned from headerActions()/bulkActions() rather than actions(). When in doubt, read the installed source and the tag matching your composer.json constraint rather than the README on main.

Extension points. Published Blade views are the supported way to customize the print/preview markup. Subclassing the action is the cleanest way to bake in company-wide defaults; avoid editing vendor files, since the next composer update will erase the change.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource