Actions
导出操作
简介
Filament 包含一个可以将行数据导出到 CSV 或者 XLSX 文件的 Action。点击触发按钮后,会打开一个模态框询问用户要导出那些列,以及这些类要使用什么标签。该特性使用了队列批量操作及数据库通知,因此你需要发布这些迁移到 Laravel 中。同时,也需要发布 Filament 用于存储导出数据的迁移表:
# Laravel 11 and higher
php artisan make:queue-batches-table
php artisan make:notifications-table
# Laravel 10
php artisan queue:batches-table
php artisan notifications:table
# All apps
php artisan vendor:publish --tag=filament-actions-migrations
php artisan migrate
NOTE
如果你使用的是 PostgreSQL,请确保通知迁移中的 data
字段使用 json()
: $table->json('data')
。
NOTE
如果 User
模型使用了 UUID,请确保通知迁移的 notifiable
字段使用 uuidMorphs()
: $table->uuidMorphs('notifiable')
ExportAction
可以像这样使用:
use App\Filament\Exports\ProductExporter;
use Filament\Actions\ExportAction;
ExportAction::make()
->exporter(ProductExporter::class)
如果你想将该 Action 添加到表头,可以这样使用:
use App\Filament\Exports\ProductExporter;
use Filament\Actions\ExportAction;
use Filament\Tables\Table;
public function table(Table $table): Table
{
return $table
->headerActions([
ExportAction::make()
->exporter(ProductExporter::class),
]);
}
Or if you want to add it as a table bulk action, so that the user can choose which rows to export, they can use Filament\Actions\ExportBulkAction
:
use App\Filament\Exports\ProductExporter;
use Filament\Actions\ExportBulkAction;
use Filament\Tables\Table;
public function table(Table $table): Table
{
return $table
->toolbarActions([
ExportBulkAction::make()
->exporter(ProductExporter::class),
]);
}
需要创建 “exporter” 类,以告知 Filament 如何导处每一行。
创建导出器
要为模型创建 exporter 类,可以使用 make:filament-exporter
命令,并传入模型名称:
php artisan make:filament-exporter Product
该命令将在 app/Filament/Exports
目录下创建一个新类。你需要定义可被导处的列字段。
自动生成导出器列
如果你想节省时间,Filament 可以使用 --generate
,基于模型的数据库字段,为你自动生成列字段:
php artisan make:filament-exporter Product --generate
定义导出器列
要定义可被导出的列,你需要在导出器类中重写 getColumns()
方法,并使其返回 ExportColumn
对象数组:
use Filament\Actions\Exports\ExportColumn;
public static function getColumns(): array
{
return [
ExportColumn::make('name'),
ExportColumn::make('sku')
->label('SKU'),
ExportColumn::make('price'),
];
}
自定义导出列标签
每个列的标签将由该列名称自动生成,不过你也可以调用 label()
方法对其进行重写:
use Filament\Actions\Exports\ExportColumn;
ExportColumn::make('sku')
->label('SKU')
配置默认选择的列
默认情况下,当用户被询问要导出哪些列时,所有的列都会被选中。你可以使用 enabledByDefault()
方法自定义默认选择的列:
use Filament\Actions\Exports\ExportColumn;
ExportColumn::make('description')
->enabledByDefault(false)
禁用列选择
默认情况下,会询问用户要导出哪些列。你可以使用 columnMapping(false)
方法禁用该功能。
use App\Filament\Exports\ProductExporter;
use Filament\Actions\ExportAction;
ExportAction::make()
->exporter(ProductExporter::class)
->columnMapping(false)
计算导出列状态
有时,你需要计算列状态,而不是直接从数据库字段中读取。
传入一个回调函数到 state()
方法,你可以自定义该列基于 $record
的返回值。
use App\Models\Order;
use Filament\Actions\Exports\ExportColumn;
ExportColumn::make('amount_including_vat')
->state(function (Order $record): float {
return $record->amount * (1 + $record->vat_rate);
})
除了 $record
之外,state()
函数可以注入各种 utility 作为参数。
Utility | Type | Parameter | Description |
---|---|---|---|
Export column | Filament\Actions\Exports\ExportColumn | $column | The current export column instance. |
Exporter | ?Filament\Actions\Exports\Exporter | $exporter | The instance of the exporter class that is currently being used for exporting data. |
Options | array<string, mixed> | $options | The options that were defined when the export started. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record that is currently being exported. |
格式化导出列值
你也可以传入一个自定义格式化回调给 formatStateUsing()
,它接受单元格的 $state
和 Eloquent 记录 $record
(可选):
use Filament\Actions\Exports\ExportColumn;
ExportColumn::make('status')
->formatStateUsing(fn (string $state): string => __("statuses.{$state}"))
除了 $state
之外,formatStateUsing()
函数可以注入各种 utility 作为参数。
Utility | Type | Parameter | Description |
---|---|---|---|
Export column | Filament\Actions\Exports\ExportColumn | $column | The current export column instance. |
Exporter | ?Filament\Actions\Exports\Exporter | $exporter | The instance of the exporter class that is currently being used for exporting data. |
Options | array<string, mixed> | $options | The options that were defined when the export started. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record that is currently being exported. |
State | mixed | $state | The state to format. |
如果列中有多个值,每个值都会调用该函数。
限制文本长度
使用 limit()
方法,你可以限制单元格中的值的长度:
use Filament\Actions\Exports\ExportColumn;
ExportColumn::make('description')
->limit(50)
除了允许静态值之外,limit()
方法也可以接受函数动态计算其值。你可以将各种 utility 作为参数注入到函数中。
Utility | Type | Parameter | Description |
---|---|---|---|
Export column | Filament\Actions\Exports\ExportColumn | $column | The current export column instance. |
Exporter | ?Filament\Actions\Exports\Exporter | $exporter | The instance of the exporter class that is currently being used for exporting data. |
Options | array<string, mixed> | $options | The options that were defined when the export started. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record that is currently being exported. |
限制字数
使用 words()
方法,你可以限制单元格中显示的字数:
use Filament\Actions\Exports\ExportColumn;
ExportColumn::make('description')
->words(10)
除了允许静态值之外,words()
方法也可以接受函数动态计算其值。你可以将各种 utility 作为参数注入到函数中。
Utility | Type | Parameter | Description |
---|---|---|---|
Export column | Filament\Actions\Exports\ExportColumn | $column | The current export column instance. |
Exporter | ?Filament\Actions\Exports\Exporter | $exporter | The instance of the exporter class that is currently being used for exporting data. |
Options | array<string, mixed> | $options | The options that were defined when the export started. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record that is currently being exported. |
添加前后缀
You may add a prefix()
or suffix()
to the cell’s value:
use Filament\Actions\Exports\ExportColumn;
ExportColumn::make('domain')
->prefix('https://')
->suffix('.com')
除了允许静态值之外,prefix()
和 suffix()
方法也可以接受函数动态计算它们值。你可以将各种 utility 作为参数注入到函数中。
Utility | Type | Parameter | Description |
---|---|---|---|
Export column | Filament\Actions\Exports\ExportColumn | $column | The current export column instance. |
Exporter | ?Filament\Actions\Exports\Exporter | $exporter | The instance of the exporter class that is currently being used for exporting data. |
Options | array<string, mixed> | $options | The options that were defined when the export started. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record that is currently being exported. |
在单元格中导出多个值
默认情况下,如果列中有多个值,将会使用逗号进行分隔。你可以使用 listAsJson()
方法将它们显示成 JSON 数组:
use Filament\Actions\Exports\ExportColumn;
ExportColumn::make('tags')
->listAsJson()
展示关联数据
你可以使用“点语法”访问关联中的列。首先是关联名,其后紧跟着点号,最后是要展示的列名:
use Filament\Actions\Exports\ExportColumn;
ExportColumn::make('author.name')
计数关联
如果你想计算列中的关联记录数量,可以使用 counts()
方法:
use Filament\Actions\Exports\ExportColumn;
ExportColumn::make('users_count')
->counts('users')
本例中,users
是要计算的关联名。列名必须为 users_count
,因为这是 Laravel 用来存储计数结果 的命名规范。
如果你想在计算前设置关联的查询范围,你可以传入一个数组到该方法中,其中键是关联名,值为设置 Eloquent 查询范围的函数:
use Filament\Actions\Exports\ExportColumn;
use Illuminate\Database\Eloquent\Builder;
ExportColumn::make('users_count')
->counts([
'users' => fn (Builder $query) => $query->where('is_active', true),
])
确定关联是否存在
如果你只是想说明列中是否存在关联记录,你可以使用 exists()
方法:
use Filament\Actions\Exports\ExportColumn;
ExportColumn::make('users_exists')
->exists('users')
本例中,users
是要检查是否存在的关联名。列名必须是 users_exists
,因为这是 Laravel 用来存储计数结果 的命名规范。
如果你想在计算前设置关联的查询范围,你可以传入一个数组到该方法中,其中键是关联名,值为设置 Eloquent 查询范围的函数:
use Filament\Actions\Exports\ExportColumn;
use Illuminate\Database\Eloquent\Builder;
ExportColumn::make('users_exists')
->exists([
'users' => fn (Builder $query) => $query->where('is_active', true),
])
聚合关联
Filament 提供多种方法用于聚合关联字段,包括 avg()
、max()
、min()
和 sum()
。比如,如果你想显示列中所有关联的平均值,你可以使用 avg()
方法:
use Filament\Actions\Exports\ExportColumn;
ExportColumn::make('users_avg_age')
->avg('users', 'age')
上例中,users
是关联名,而 age
是要计算平均值的字段。列名必须是 users_avg_age
,因为这是 Laravel 用来存储聚合结果 的命名规范。
如果你想在计算前设置关联的查询范围,你可以传入一个数组到该方法中,其中键是关联名,值为设置 Eloquent 查询范围的函数:
use Filament\Actions\Exports\ExportColumn;
use Illuminate\Database\Eloquent\Builder;
ExportColumn::make('users_avg_age')
->avg([
'users' => fn (Builder $query) => $query->where('is_active', true),
], 'age')
配置导出格式
默认情况下,导出 Action 会允许用户在 CSV 和 XLSX 格式之间做出选择。你可以在 Action 的 formats()
方法中传入一个格式数组,使用 ExportFormat
枚举对此进行自定义:
use App\Filament\Exports\ProductExporter;
use Filament\Actions\ExportAction;
use Filament\Actions\Exports\Enums\ExportFormat;
ExportAction::make()
->exporter(ProductExporter::class)
->formats([
ExportFormat::Csv,
])
// or
->formats([
ExportFormat::Xlsx,
])
// or
->formats([
ExportFormat::Xlsx,
ExportFormat::Csv,
])
此外,你可以在导出器类中重写 getFormats()
方法,为所有使用该导出器的 Action 设置默认格式:
use Filament\Actions\Exports\Enums\ExportFormat;
public function getFormats(): array
{
return [
ExportFormat::Csv,
];
}
修改导出查询
By default, if you are using the ExportAction
with a table, the action will use the table’s currently filtered and sorted query to export the data. If you don’t have a table, it will use the model’s default query. To modify the query builder before exporting, you can use the modifyQueryUsing()
method on the action:
use App\Filament\Exports\ProductExporter;
use Filament\Actions\ExportAction;
use Illuminate\Database\Eloquent\Builder;
ExportAction::make()
->exporter(ProductExporter::class)
->modifyQueryUsing(fn (Builder $query) => $query->where('is_active', true))
You may inject the $options
argument into the function, which is an array of options for that export:
use App\Filament\Exports\ProductExporter;
use Illuminate\Database\Eloquent\Builder;
ExportAction::make()
->exporter(ProductExporter::class)
->modifyQueryUsing(fn (Builder $query, array $options) => $query->where('is_active', $options['isActive'] ?? true))
Alternatively, you can override the modifyQuery()
method on the exporter class, which will modify the query for all actions that use that exporter:
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\MorphTo;
public static function modifyQuery(Builder $query): Builder
{
return $query->with([
'purchasable' => fn (MorphTo $morphTo) => $morphTo->morphWith([
ProductPurchase::class => ['product'],
ServicePurchase::class => ['service'],
Subscription::class => ['plan'],
]),
]);
}
配置导出文件系统
自定义存储磁盘
默认情况下,导出文件会上传到配置文件中定义的存储磁盘中(默认为 public
)。你也可以设置 FILAMENT_FILESYSTEM_DISK
环境变量来修改他。
虽然使用 public
磁盘是 Filament 许多包的默认设置,但将其用于导出会导致导出的文件存储在公共位置。因此,如果默认的文件系统磁盘是public
,并且你的 config/filesystems.php
中存在 local
磁盘,Filament 将使用 local
盘进行导出。如果你为 ExportAction
或导出器类将磁盘重写为 public
,Filament 将使用它。
在生产环境中,你应该使用具有私有访问策略的磁盘,如 s3
,以防止对导出文件的未经授权的访问。
如果你想为特定的导出使用不同的磁盘,你可以将磁盘名称传递给操作上的 disk()
方法:
use Filament\Actions\ExportAction;
ExportAction::make()
->exporter(ProductExporter::class)
->fileDisk('s3')
你可以在服务提供者(比如 AppServiceProvider
)的 boot()
方法中一次性设置所有导出 Action 的磁盘:
use Filament\Actions\ExportAction;
ExportAction::configureUsing(fn (ExportAction $action) => $action->fileDisk('s3'));
此外,你也可以重写导出器类的 getFileDisk()
,使之返回磁盘名:
public function getFileDisk(): string
{
return 's3';
}
如果开发者愿意,他们有责任删除创建的导出文件。Filament 不会删除这些文件,以防以后需要再次下载导出。
配置导出文件名
默认情况下,导出文件的名称是基于ID 和导出类型生成的。你可以在 Action 上使用 fileName()
方法,自定义文件名:
use Filament\Actions\ExportAction;
use Filament\Actions\Exports\Models\Export;
ExportAction::make()
->exporter(ProductExporter::class)
->fileName(fn (Export $export): string => "products-{$export->getKey()}.csv")
此外,你也可以重写导出器类的 getFileName()
,使之返回字符串:
use Filament\Actions\Exports\Models\Export;
public function getFileName(Export $export): string
{
return "products-{$export->getKey()}.csv";
}
使用导出选项
导出操作可以渲染用户在导出 CSV 时可以与之交互的额外表单组件。这对于允许用户自定义导出器的行为非常有用。例如,你可能希望用户在导出时能够选择特定列的格式。为此,你可以在导出器类上的 getOptionsFormComponent()
方法返回选项表单组件:
use Filament\Forms\Components\TextInput;
public static function getOptionsFormComponents(): array
{
return [
TextInput::make('descriptionLimit')
->label('Limit the length of the description column content')
->integer(),
];
}
此外,你也可以通过 Action 的 option()
方法传递一组静态选项给导出器:
use App\Filament\Exports\ProductExporter;
use Filament\Actions\ExportAction;
ExportAction::make()
->exporter(ProductExporter::class)
->options([
'descriptionLimit' => 250,
])
除了允许静态值之外,options()
方法也可以接受函数动态计算其值。你可以将各种 utility 作为参数注入到函数中。
Learn more about utility injection.
Utility | Type | Parameter | Description |
---|---|---|---|
Action | Filament\Actions\Action | $action | The current action instance. |
Arguments | array<string, mixed> | $arguments | The array of arguments passed to the action when it was triggered. |
Data | array<string, mixed> | $data | The array of data submitted from form fields in the action's modal. It will be empty before the modal form is submitted. |
Livewire | Livewire\Component | $livewire | The Livewire component instance. |
Eloquent model FQN | ?string<Illuminate\Database\Eloquent\Model> | $model | The Eloquent model FQN for the current action, if one is attached. |
Mounted actions | array<Filament\Actions\Action> | $mountedActions | The array of actions that are currently mounted in the Livewire component. This is useful for accessing data from parent actions. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record for the current action, if one is attached. |
Schema | Filament\Schemas\Schema | $schema | [Actions in schemas only] The schema object that this action belongs to. |
Schema component | Filament\Schemas\Components\Component | $schemaComponent | [Actions in schemas only] The schema component that this action belongs to. |
Schema component state | mixed | $schemaComponentState | [Actions in schemas only] The current value of the schema component. |
Schema get function | Filament\Schemas\Components\Utilities\Get | $schemaGet | [Actions in schemas only] A function for retrieving values from the schema data. Validation is not run on form fields. |
Schema operation | string | $schemaOperation | [Actions in schemas only] The current operation being performed by the schema. Usually create , edit , or view . |
Schema set function | Filament\Schemas\Components\Utilities\Set | $schemaSet | [Actions in schemas only] A function for setting values in the schema data. |
Selected Eloquent records | Illuminate\Support\Collection | $selectedRecords | [Bulk actions only] The Eloquent records selected in the table. |
Table | Filament\Tables\Table | $table | [Actions in tables only] The table object that this action belongs to. |
现在,通过将 $options
参数注入到闭包函数中,你可以在导出类中访问这些选项的数据。比如,如果你想在 formatStateUsing()
中使用它们来格式化列值:
use Filament\Actions\Exports\ExportColumn;
ExportColumn::make('description')
->formatStateUsing(function (string $state, array $options): string {
return (string) str($state)->limit($options['descriptionLimit'] ?? 100);
})
此外,因为 $options
参数被传入到所有闭包函数中,你可以在 limit()
中访问:
use Filament\Actions\Exports\ExportColumn;
ExportColumn::make('description')
->limit(fn (array $options): int => $options['descriptionLimit'] ?? 100)
使用自定义用户模型
默认情况下,exports
表有一个 user_id
列。该列被约束到 users
表:
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
在 Export
模型中,user()
关联被定义指向 App\Models\User
模型的 BelongsTo
关联。如果 App\Models\User
模型不存在,或者你想使用其他模型,你可以在服务提供者的 register()
方法中将新的 Authenticatable
模型绑定到容器中:
use App\Models\Admin;
use Illuminate\Contracts\Auth\Authenticatable;
$this->app->bind(Authenticatable::class, Admin::class);
如果 authenticatable 模型使用了不同于 users
的表,你应该将其表名传入到 constrained()
中:
$table->foreignId('user_id')->constrained('admins')->cascadeOnDelete();
使用多态用户关联
如果你希望使用多个用户模型关联导出,你可以使用多态 MorphTo
关联。为此,你需要在 exports
表中替换 user_id
列:
$table->morphs('user');
然后,在服务提供者的 boot()
方法中,你应该调用 Export::polymorphicUserRelationship()
,将 Export
模型上的 user
关联修改为 MorphTo
关联:
use Filament\Actions\Exports\Models\Export;
Export::polymorphicUserRelationship();
限制可导出的最大行数
要防止服务器过载,你可能会希望限制一个 CSV 文件导出的最大行数。为此,你可以在 Action 上调用 maxRows()
方法:
use App\Filament\Exports\ProductExporter;
use Filament\Actions\ExportAction;
ExportAction::make()
->exporter(ProductExporter::class)
->maxRows(100000)
修改导出分块大小
Filament 将对 CSV 进行分块(chunk),并在不同的队列作业中处理每个分块。默认情况下,每个块是 100 行。你可以在 Action 上调用 chunkSize()
方法来修改:
use App\Filament\Exports\ProductExporter;
use Filament\Actions\ExportAction;
ExportAction::make()
->exporter(ProductExporter::class)
->chunkSize(250)
除了允许静态值之外,chunkSize()
方法也可以接受函数动态计算其值。你可以将各种 utility 作为参数注入到函数中。
Learn more about utility injection.
Utility | Type | Parameter | Description |
---|---|---|---|
Action | Filament\Actions\Action | $action | The current action instance. |
Arguments | array<string, mixed> | $arguments | The array of arguments passed to the action when it was triggered. |
Data | array<string, mixed> | $data | The array of data submitted from form fields in the action's modal. It will be empty before the modal form is submitted. |
Livewire | Livewire\Component | $livewire | The Livewire component instance. |
Eloquent model FQN | ?string<Illuminate\Database\Eloquent\Model> | $model | The Eloquent model FQN for the current action, if one is attached. |
Mounted actions | array<Filament\Actions\Action> | $mountedActions | The array of actions that are currently mounted in the Livewire component. This is useful for accessing data from parent actions. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record for the current action, if one is attached. |
Schema | Filament\Schemas\Schema | $schema | [Actions in schemas only] The schema object that this action belongs to. |
Schema component | Filament\Schemas\Components\Component | $schemaComponent | [Actions in schemas only] The schema component that this action belongs to. |
Schema component state | mixed | $schemaComponentState | [Actions in schemas only] The current value of the schema component. |
Schema get function | Filament\Schemas\Components\Utilities\Get | $schemaGet | [Actions in schemas only] A function for retrieving values from the schema data. Validation is not run on form fields. |
Schema operation | string | $schemaOperation | [Actions in schemas only] The current operation being performed by the schema. Usually create , edit , or view . |
Schema set function | Filament\Schemas\Components\Utilities\Set | $schemaSet | [Actions in schemas only] A function for setting values in the schema data. |
Selected Eloquent records | Illuminate\Support\Collection | $selectedRecords | [Bulk actions only] The Eloquent records selected in the table. |
Table | Filament\Tables\Table | $table | [Actions in tables only] The table object that this action belongs to. |
TIP
如果你在导入大型 CSV 文件时遇到内存问题或者出现超时,缩减分块大小或许就是一个不错的方案。
修改 CSV 分隔符
默认的 CSV 分隔符是逗号(,
)。如果你想要其他分隔符进行导出,你可以重写该 Expoerter 类上的 getCsvDelimiter()
方法,并返回新的分隔符:
public static function getCsvDelimiter(): string
{
return ';';
}
除了允许静态值之外,csvDelimiter()
方法也可以接受函数动态计算其值。你可以将各种 utility 作为参数注入到函数中。
Learn more about utility injection.
Utility | Type | Parameter | Description |
---|---|---|---|
Action | Filament\Actions\Action | $action | The current action instance. |
Arguments | array<string, mixed> | $arguments | The array of arguments passed to the action when it was triggered. |
Data | array<string, mixed> | $data | The array of data submitted from form fields in the action's modal. It will be empty before the modal form is submitted. |
Livewire | Livewire\Component | $livewire | The Livewire component instance. |
Eloquent model FQN | ?string<Illuminate\Database\Eloquent\Model> | $model | The Eloquent model FQN for the current action, if one is attached. |
Mounted actions | array<Filament\Actions\Action> | $mountedActions | The array of actions that are currently mounted in the Livewire component. This is useful for accessing data from parent actions. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record for the current action, if one is attached. |
Schema | Filament\Schemas\Schema | $schema | [Actions in schemas only] The schema object that this action belongs to. |
Schema component | Filament\Schemas\Components\Component | $schemaComponent | [Actions in schemas only] The schema component that this action belongs to. |
Schema component state | mixed | $schemaComponentState | [Actions in schemas only] The current value of the schema component. |
Schema get function | Filament\Schemas\Components\Utilities\Get | $schemaGet | [Actions in schemas only] A function for retrieving values from the schema data. Validation is not run on form fields. |
Schema operation | string | $schemaOperation | [Actions in schemas only] The current operation being performed by the schema. Usually create , edit , or view . |
Schema set function | Filament\Schemas\Components\Utilities\Set | $schemaSet | [Actions in schemas only] A function for setting values in the schema data. |
Selected Eloquent records | Illuminate\Support\Collection | $selectedRecords | [Bulk actions only] The Eloquent records selected in the table. |
Table | Filament\Tables\Table | $table | [Actions in tables only] The table object that this action belongs to. |
你只能指定单个字符,否则会抛出异常。
自定义 XLSX 文件
XLSX 行样式
如果你想设置 XLSX 文件的单元格样式,你可以重写导出器类的 getXlsxCellStyle()
,使之返回 OpenSpout Style
对象:
use OpenSpout\Common\Entity\Style\Style;
public function getXlsxCellStyle(): ?Style
{
return (new Style())
->setFontSize(12)
->setFontName('Consolas');
}
如果你只想修改 XLSX 文件的标题单元格样式,你可以重写导出器类的 getXlsxHeaderCellStyle()
,使之返回 OpenSpout Style
对象:
use OpenSpout\Common\Entity\Style\CellAlignment;
use OpenSpout\Common\Entity\Style\CellVerticalAlignment;
use OpenSpout\Common\Entity\Style\Color;
use OpenSpout\Common\Entity\Style\Style;
public function getXlsxHeaderCellStyle(): ?Style
{
return (new Style())
->setFontBold()
->setFontItalic()
->setFontSize(14)
->setFontName('Consolas')
->setFontColor(Color::rgb(255, 255, 77))
->setBackgroundColor(Color::rgb(0, 0, 0))
->setCellAlignment(CellAlignment::CENTER)
->setCellVerticalAlignment(CellVerticalAlignment::CENTER);
}
XLSX 列样式
导出器类上的 makeXlsxRow()
和 makeXlsxHeaderRow()
方法允许你在某一行内自定义单独的单元格样式。默认情况下,该方法的实现如下:
use OpenSpout\Common\Entity\Row;
use OpenSpout\Common\Entity\Style\Style;
/**
* @param array<mixed> $values
*/
public function makeXlsxRow(array $values, ?Style $style = null): Row
{
return Row::fromValues($values, $style);
}
用户导出时,他们可以选择导出哪些行。因此,$this->columnMap
属性可以用于确定哪些行以何种顺序导出。你可以将 Row::fromValues()
替换成一个 Cell
对象数组,以允许你使用 OpenSpout Style
对象单独设置样式。StyleMerger
可以用于将单元格的自定义样式与默认样式进行合并,允许你在默认样式基础上应用其他样式:
use OpenSpout\Common\Entity\Cell;
use OpenSpout\Common\Entity\Row;
use OpenSpout\Common\Entity\Style\Style;
use OpenSpout\Writer\Common\Manager\Style\StyleMerger;
/**
* @param array<mixed> $values
*/
public function makeXlsxRow(array $values, ?Style $style = null): Row
{
$styleMerger = new StyleMerger();
$cells = [];
foreach (array_keys($this->columnMap) as $columnIndex => $column) {
$cells[] = match ($column) {
'name' => Cell::fromValue(
$values[$columnIndex],
$styleMerger->merge(
(new Style())->setFontUnderline(),
$style,
),
),
'price' => Cell::fromValue(
$values[$columnIndex],
(new Style())->setFontSize(12),
),
default => Cell::fromValue($values[$columnIndex]),
},
}
return new Row($cells, $style);
}
自定义 XLSX writer
如果你想要传递选项给 OpenSpout XLSX Writer
,你可以在导出器类的 getXlsxWriterOptions()
方法中返回 OpenSpout\Writer\XLSX\Options
实例:
use OpenSpout\Writer\XLSX\Options;
public function getXlsxWriterOptions(): ?Options
{
$options = new Options();
$options->setColumnWidth(10, 1);
$options->setColumnWidthForRange(12, 2, 3);
return $options;
}
如果你想在其关闭前自定义 XLSX writer,你可以在导出器类上重写 configureXlsxWriterBeforeClosing()
。该方法接收 Writer
实例作为参数,你可以在其关闭之前修改它。
use OpenSpout\Writer\XLSX\Entity\SheetView;
use OpenSpout\Writer\XLSX\Writer;
public function configureXlsxWriterBeforeClose(Writer $writer): Writer
{
$sheetView = new SheetView();
$sheetView->setFreezeRow(2);
$sheetView->setFreezeColumn('B');
$sheet = $writer->getCurrentSheet();
$sheet->setSheetView($sheetView);
$sheet->setName('export');
return $writer;
}
自定义导出任务
处理导出任务的默认 job 是 Filament\Actions\Exports\Jobs\PrepareCsvExport
。如果想继承该类并重写它的方法,你可以在服务提供者的 register()
方法中替换掉原来的类:
use App\Jobs\PrepareCsvExport;
use Filament\Actions\Exports\Jobs\PrepareCsvExport as BasePrepareCsvExport;
$this->app->bind(BasePrepareCsvExport::class, PrepareCsvExport::class);
或者,也可以将新的 Job 类传入到 Action 的 job()
方法中,以自定义特定导出任务:
use App\Filament\Exports\ProductExporter;
use App\Jobs\PrepareCsvExport;
use Filament\Actions\ExportAction;
ExportAction::make()
->exporter(ProductExporter::class)
->job(PrepareCsvExport::class)
自定义导出队列和连接
默认情况下,导出系统将使用默认队列和连接。如果你想自定义用于特定导出器的 Job 队列,你可以在你的导出器类中重写 getJobQueue()
方法:
public function getJobQueue(): ?string
{
return 'exports';
}
重写你的导出类中的 getJobConnection()
方法,你也可以自定义用于特定导出器的 Job 连接:
public function getJobConnection(): ?string
{
return 'sqs';
}
自定义导出任务中间件
默认情况下,导出系统每次导出时只会处理一个任务。这是为了防止服务器过载,也为了防止其他任务因大量导出而延迟。该功能在导出器类的 WithoutOverlapping
中间件中定义:
public function getJobMiddleware(): array
{
return [
(new WithoutOverlapping("export{$this->export->getKey()}"))->expireAfter(600),
];
}
如果你想自定义应用于某个导出器的 Job 所应用的中间件,你可以在导出类中重写此方法。更多关于 Job 中间件的信息,请查阅 Laravel 文档。
自定义导出任务重试
默认情况下,导出系统会在 24 小时内重试任务,或者重试任务直到因未处理异常而失败 5 次时(以先发生为准)。这是为了解决临时问题,比如数据库不可用。你可以修改 Job 的重试时间周期,它在导出器类的 getJobRetryUntil()
方法中定义:
use Carbon\CarbonInterface;
public function getJobRetryUntil(): ?CarbonInterface
{
return now()->addHours(12);
}
更多关于 Job 重试的信息,请查阅 Laravel 文档。
自定义导出任务退避策略
默认情况下,导出系统在重试之前会等待 1 分钟,然后等待 2 分钟,随后是 5 分钟,最后是 10 分钟。这是为了防止服务器因任务反复失败而过载。此功能在导出器类的 getJobBackoff()
方法中定义:
/**
* @return int | array<int> | null
*/
public function getJobBackoff(): int | array | null
{
return [60, 120, 300, 600];
}
你可以在 Laravel 文档中阅读有关任务退避的更多信息,包括如何配置指数退避。
自定义导出任务标签
默认情况下,导出系统会使用导入的 ID 来标记每个任务。这是为了方便轻你松找到与特定导出相关的所有任务。此功能在导出器类的 getJobTags()
方法中定义:
public function getJobTags(): array
{
return ["export{$this->export->getKey()}"];
}
如果你想自定义应用于特定导出器作业的标签,你可以在导出器类中重写此方法。
自定义导出任务批次名
默认情况下,导出系统不会为任务批次定义任何名称。如果你想自定义应用于特定导出器任务批次的名称,可以在导出器类中重写 getJobBatchName()
方法:
public function getJobBatchName(): ?string
{
return 'product-export';
}
授权
默认情况下,只有开启导出的用户才能下载器生成的文件。如果你想自定义授权逻辑,可以创建一个 ExportPolicy
类,并在 AuthServiceProvider
中注册它:
use App\Policies\ExportPolicy;
use Filament\Actions\Exports\Models\Export;
protected $policies = [
Export::class => ExportPolicy::class,
];
该策略的 view()
方法将用于授权访问下载。
请注意,如果你定义了策略,现有的逻辑(即只有开启导出的用户才可以访问)将被移除。如果你要保留该逻辑,你需要将其添加到策略中:
use App\Models\User;
use Filament\Actions\Exports\Models\Export;
public function view(User $user, Export $export): bool
{
return $export->user()->is($user);
}
Edit on GitHubStill need help? Join our Discord community or open a GitHub discussion