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
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.