Exporting and importing data from an Excel file is very common. In this tutorial, we will use pxlrbt/filament-excel
for exporting and konnco/filament-import
for importing data.
Importing Data
First, we must install the package via composer.
composer require konnco/filament-import:"^2.0"
When writing this tutorial, this package is in beta for supporting Filament v3. You need to set
minimum-stability
tobeta
.
composer.json:
{ // ... "minimum-stability": "beta", "prefer-stable": true}
We can add an Import
action to the header actions list. This is done in the ListRecords
page for your Resource.
use Konnco\FilamentImport\Actions\ImportField;use Konnco\FilamentImport\Actions\ImportAction; class ListItems extends ListRecords{ protected static string $resource = ItemResource::class; protected function getHeaderActions(): array { return [ Actions\CreateAction::make(), ImportAction::make() ->uniqueField('name') ->fields([ ImportField::make('name') ->required(), ImportField::make('category.name') ->required() ->label('Category name'), ImportField::make('stock') ->required(), ]), ]; }}
Now, we can see an action button in the tables header.
After uploading a file, we can select a column.
Great, that should work now, right? It would work if the category weren't in the relation in this example. For this case, the package allows to manually create records.
use App\Models\Item;use App\Filament\Resources\CategoryResource;use Konnco\FilamentImport\Actions\ImportField;use Konnco\FilamentImport\Actions\ImportAction; class ListItems extends ListRecords{ protected static string $resource = ItemResource::class; protected function getHeaderActions(): array { return [ Actions\CreateAction::make(), ImportAction::make() ->uniqueField('name') ->fields([ ImportField::make('name') ->required(), ImportField::make('category.name') ->required() ->label('Category name'), ImportField::make('stock') ->required(), ]) ->handleRecordCreation(function(array $data) { if ($category = CategoryResource::getEloquentQuery()->where('name', $data['category']['name'])->first()) { return Item::create([ 'name' => $data['name'], 'current_stock' => $data['stock'], 'category_id' => $category->id, ]); } return new Item(); }), ]; }}
If the category exists, we only create a new record from the Excel import in this example. The handleRecordCreation
method needs to return a Model. That's why we return the created Model or a new Model instance.
For more available options, check the package documentation.
Exporting Data
As always, the package can be installed via composer.
composer require psr/simple-cache:^2.0 pxlrbt/filament-excel
Next, we need to action button in the ListRecords
page for your Resource.
use pxlrbt\FilamentExcel\Columns\Column;use pxlrbt\FilamentExcel\Exports\ExcelExport;use pxlrbt\FilamentExcel\Actions\Pages\ExportAction; class ListItems extends ListRecords{ protected static string $resource = ItemResource::class; protected function getHeaderActions(): array { return [ Actions\CreateAction::make(), ImportAction::make() ->uniqueField('name') ->fields([ ImportField::make('name') ->required(), ImportField::make('category.name') ->required() ->label('Category name'), ImportField::make('stock') ->required(), ]) ->handleRecordCreation(function(array $data) { if ($category = CategoryResource::getEloquentQuery()->where('name', $data['category']['name'])->first()) { return Item::create([ 'name' => $data['name'], 'current_stock' => $data['stock'], 'category_id' => $category->id, ]); } return new Item(); }), ExportAction::make() ->exports([ ExcelExport::make() ->fromTable() ->withFilename(fn ($resource) => $resource::getModelLabel() . '-' . date('Y-m-d')) ->withWriterType(\Maatwebsite\Excel\Excel::CSV) ->withColumns([ Column::make('updated_at'), ]) ]), ]; }}
Now, we can see an action button in the tables header.
Because we are exporting from the table, all fields are resolved from that, but using the withColumns
method, we add an additional field, updated_at
.
We also provide the filename using the withFilename
method. And because this package uses the laravel-excel package under the hood, the file type in the withWriterType
method is provided using the laravel-excel package.
After pressing the export button, we download the exported data as a CSV file.
If you want more Filament examples, you can find more real-life projects on our FilamentExamples.com.
Hi! I'm using Filament Table in a Livewitre project, and I would like to execute the export from a livewire component outside the table. I've been trying diferents way but it does not download anything, and no errors. Any thought how to implement it?
If you are trying to export the table with current filters applied you can try put your download button in a Widget. Add 'use ExposesTableToWidgets;' to your ListRecords. Then you can use $this->getPageTableQuery() to help you prepare download in the widget. https://filamentphp.com/docs/3.x/panels/resources/widgets#accessing-page-table-data-in-the-widget
it doesn't work!
I'm using konnco/filament-import with Filament V3. I did update my composer file like so "minimum-stability": "beta", "prefer-stable": true
However the "Match data to column" fields were not populating even though the csv file was uploaded to storage.
Lost quite some time until I figured I also need to specify the version "konnco/filament-import": "v2.0.0-beta",
Finally works for me and probably worth mentioning.
Updated the install command
why select column name not show when import excel
I have a table column that combines a few fields using ->formatStateUsing() Is there anyway to get ExportBulkAction::make() to output this field properly? Currently is only exports empty square brakets.
Idea of that I am doing:
TextColumn::make('staff_title')->formatStateUsing(fn ($state, Activity $staff) => $staff->staff_title . ' ' . $staff->first_name . $staff->last_name) ... ExportBulkAction::make()
Are you tal about this? https://filamentphp.com/plugins/pxlrbt-excel#formatting
I've used that doco and getHeaderActions()->ExportAction->ExcelExport->withColumns()->Column->formatStateUsing()
While it works, it only adds a button to the header and doesnt interact with the checkbox selection like ExportBulkAction. I really need to make a header action use the checkboxes or to do the same formatting on the bulk action.
Oh I am a right spoon ignore me... I can just add all the code from ExportAction::make() ... that was working to ExportBulkAction::make()
Appologies and thanks.
Please how can we customize the notifications?
Would be better to ask package
I have an importAction that I would like to invoke from a route. How do I create, or retrieve from filament, a route to that action?
Use a native import feature introduced in v3.1
How we can do any action after export, like update exported flag true in table?
Refer to package author
Okay, Thanks for reply
i have run this it'work for me, if i use this "TextColumn::make('money') ->formatStateUsing(function ($state) { return Str::replace('USD', '$', format_money($state, 'USD')); })," why iget this error "Filament\Support\format_money(): Argument #1 ($money) must be of type int|float, string given,", how to fix that ? can anyone help me ?
You pass the string but it needs to be integer or float.
Nice and simple
Hi, I'm using the native filament export action, but I want to immediately download the csv/xlsx file without a background process. How can I achieve that? Also, I'm creating an exports table manually because it getting the error "no such tables exports" or something when exporting. Is there any way to publish the migration for the exports table? I don't bother creating an export table, though; I just want to immediately download the file after exporting.
You haven't read the docs. You should publish everything that is needed, migrations are included. As for downloading immediately with the native action I don't think it's possible because filament dispatches a job to create the file.
Yup, thank you, I want to edit my comment just now. I have found a way to publish exports, imports, etc. But, do I need configure some broadcasting/pusher for this to working properly? Can I just download the file?
Edit again: The "success" pop-up modal export started showed, but I don't received any notification from database notification
When the export is completed you get a notification. The db notifications must be enabled first
How to enable it? isn't it as simple as adding migration table as shown in this docs. I've also added databaseNotifications() to my panel.
Read filament docs https://filamentphp.com/docs/3.x/notifications/database-notifications
Yes, I've read all of it and has added databaseNotifications() to my panel. Can you point exactly where or how I can received notification with download button of excel file after filament export success? Should I manually create notification for that? Can you guide me through it?
The records are showing in the database table, but with 0 successful_rows, I think the export processes are failed probably? Where or how can I debug it?
Have you first run the queue? If everything is set correctly you should see a notification