表格

Summaries

简介

你可以在表格内容下方渲染一个“汇总”区间。这非常适合于在表格中显示诸如数据平均值、总和、计数和范围之类的计算结果。

默认情况下,当前数据页会显示一行汇总,如果有多个可用页面,则会显示一行用于显示所有数据总计的附加汇总。你还可以为记录添加汇总,请参阅“行分组汇总”

可以使用 summarize() 方法将 “Summarizer” 对象添加到任何表格列中:

use Filament\Tables\Columns\Summarizers\Average;
use Filament\Tables\Columns\TextColumn;

TextColumn::make('rating')
    ->summarize(Average::make())

同一个列可以添加多个汇总:

use Filament\Tables\Columns\Summarizers\Average;
use Filament\Tables\Columns\Summarizers\Range;
use Filament\Tables\Columns\TextColumn;

TextColumn::make('rating')
    ->numeric()
    ->summarize([
        Average::make(),
        Range::make(),
    ])

表格中的第一列不能使用汇总器。该列用于渲染汇总区域的标题和副标题。

Table with summaries

可用汇总器

Filament 自带四类汇总器:

你也可以创建自定义汇总器,用你希望的方式展示数据。

平均值

平均值用来计算数据集中所有值的平均值:

use Filament\Tables\Columns\Summarizers\Average;
use Filament\Tables\Columns\TextColumn;

TextColumn::make('rating')
    ->summarize(Average::make())

上例中,表格中的所有评分(rating)都会将被加在一起,然后除以评分个数。

Table with average summary

计数

Count 可用于查找数据集中值的总数。除非你只想计算行数,否则你可能还需要确定数据集的范围

use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\Summarizers\Count;
use Illuminate\Database\Query\Builder;

IconColumn::make('is_published')
    ->boolean()
    ->summarize(
        Count::make()->query(fn (Builder $query) => $query->where('is_published', true)),
    ),

上例中,表格会计算发布了多少篇文章。

计算图标的出现次数

图标列中使用计数器允许你使用 icons() 方法,为用户提供表格中每个图标数量的直观表示:

use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\Summarizers\Count;
use Illuminate\Database\Query\Builder;

IconColumn::make('is_published')
    ->boolean()
    ->summarize(Count::make()->icons()),
Table with icon count summary

范围

范围可用于计算数据集中的最小值和最大值:

use Filament\Tables\Columns\Summarizers\Range;
use Filament\Tables\Columns\TextColumn;

TextColumn::make('price')
    ->summarize(Range::make())

本例中,将会寻找表格中的最低价格和最高价格。

Table with range summary

日期范围

你可以使用 minimalDateTimeDifference() 方法将范围格式化为日期:

use Filament\Tables\Columns\Summarizers\Range;
use Filament\Tables\Columns\TextColumn;

TextColumn::make('created_at')
    ->dateTime()
    ->summarize(Range::make()->minimalDateTimeDifference())

此方法将显示最小日期和最大日期之间的最小差异。例如:

  • 如果最小日期和最大日期不同,则仅显示日期。
  • 如果最小日期和最大日期在同一天的不同时间,则将同时显示日期和时间。
  • 如果最小日期和最大日期及时间相同,则仅显示一次。

文本范围

你可以使用 minimalTextualDifference() 方法将范围格式化为文本:

use Filament\Tables\Columns\Summarizers\Range;
use Filament\Tables\Columns\TextColumn;

TextColumn::make('sku')
    ->summarize(Range::make()->minimalTextualDifference())

此方法将显示最小值和最大值之间的最小差异。例如:

  • 如果最小值和最大值的首字母不同,则仅显示首字母。
  • 如果最小值和最大值的首字母相同,则将渲染更多文本,直到找到差异。
  • 如果最小值和最大值相同,则它们仅显示一次。

在范围中包含 null 值

默认情况下,我们会从范围中排除空值(null)。如果你想包含它们,可以使用 excludeNull(false) 方法:

use Filament\Tables\Columns\Summarizers\Range;
use Filament\Tables\Columns\TextColumn;

TextColumn::make('sku')
    ->summarize(Range::make()->excludeNull(false))

总和

总和(Sum)用于计算数据集中所有数据的总和:

use Filament\Tables\Columns\Summarizers\Sum;
use Filament\Tables\Columns\TextColumn;

TextColumn::make('price')
    ->summarize(Sum::make())

上例中,表格里所有的价格将会加到一起。

Table with sum summary

设置标签

使用 label() 方法,你可以设置汇总器的标签:

use Filament\Tables\Columns\Summarizers\Sum;
use Filament\Tables\Columns\TextColumn;

TextColumn::make('price')
    ->summarize(Sum::make()->label('Total'))

Hiding a summarizer’s label

It may be tempting to set the label to an empty string to hide it, but this is not recommended. Setting the label to an empty string will not communicate the purpose of the summarizer to screen readers, even if the purpose is clear visually. Instead, you should use the hiddenLabel() method, so it is hidden visually but still accessible to screen readers:

use Filament\Tables\Columns\Summarizers\Sum;
use Filament\Tables\Columns\TextColumn;

TextColumn::make('price')
    ->summarize(Sum::make()->hiddenLabel())

You can also conditionally hide the label:

use Filament\Tables\Columns\Summarizers\Sum;
use Filament\Tables\Columns\TextColumn;

TextColumn::make('price')
    ->summarize(Sum::make()->hiddenLabel(FeatureFlag::active()))

设置数据集查询范围

使用 query() 方法,你可以限制汇总器数据集的数据库查询范围:

use Filament\Tables\Columns\Summarizers\Average;
use Filament\Tables\Columns\TextColumn;
use Illuminate\Database\Query\Builder;

TextColumn::make('rating')
    ->summarize(
        Average::make()->query(fn (Builder $query) => $query->where('is_published', true)),
    ),

上例中,只有 is_published 设置为 true 的记录会被用于计算平均值。

该功能在使用计数汇总器时尤其有用,它可以计算数据集中有多少记录通过测试:

use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\Summarizers\Count;
use Illuminate\Database\Query\Builder;

IconColumn::make('is_published')
    ->boolean()
    ->summarize(
        Count::make()->query(fn (Builder $query) => $query->where('is_published', true)),
    ),

本例中,表格会计算发布了多少篇文章。

格式化

数字格式化

numeric() 方法用于将条目格式化为数字:

use Filament\Tables\Columns\Summarizers\Average;
use Filament\Tables\Columns\TextColumn;

TextColumn::make('rating')
    ->summarize(Average::make()->numeric())

如果你想自定义用于格式化数字的小数点位数,你可以使用 decimalPlaces 参数:

use Filament\Tables\Columns\Summarizers\Average;
use Filament\Tables\Columns\TextColumn;

TextColumn::make('rating')
    ->summarize(Average::make()->numeric(
        decimalPlaces: 0,
    ))

默认情况下,将会使用应用的当前语言环境来格式化数字。如果你想自定义使用的语言环境,你可以将其传递给 locale 参数:

use Filament\Tables\Columns\Summarizers\Average;
use Filament\Tables\Columns\TextColumn;

TextColumn::make('rating')
    ->summarize(Average::make()->numeric(
        locale: 'nl',
    ))

货币格式化

money() 方法用于格式任何货币的金额值:

use Filament\Tables\Columns\Summarizers\Sum;
use Filament\Tables\Columns\TextColumn;

TextColumn::make('price')
    ->summarize(Sum::make()->money('EUR'))

money() 还有一个 divideBy 参数,允许你在格式化之前将原始值除以一个数字。如果你的数据库以美分存储价格,这可能会很有用,比如:

use Filament\Tables\Columns\Summarizers\Sum;
use Filament\Tables\Columns\TextColumn;

TextColumn::make('price')
    ->summarize(Sum::make()->money('EUR', divideBy: 100))

默认情况下,将会使用应用的当前语言环境来格式化金额。如果你想自定义使用的语言环境,你可以将其传递给 locale 参数:

use Filament\Tables\Columns\Summarizers\Average;
use Filament\Tables\Columns\TextColumn;

TextColumn::make('price')
    ->summarize(Sum::make()->money('EUR', locale: 'nl'))

如果你想自定义用于格式化数字的小数点位数,你可以使用 decimalPlaces 参数:

use Filament\Tables\Columns\TextColumn;

TextColumn::make('price')
    ->summarize(Sum::make()->money('EUR', decimalPlaces: 3))

限制文本长度

使用 limit(),你可以限制汇总值的长度:

use Filament\Tables\Columns\Summarizers\Range;
use Filament\Tables\Columns\TextColumn;

TextColumn::make('sku')
    ->summarize(Range::make()->limit(5))

添加前后缀

你可以向汇总值添加前缀或者后缀:

use Filament\Tables\Columns\Summarizers\Sum;
use Filament\Tables\Columns\TextColumn;
use Illuminate\Support\HtmlString;

TextColumn::make('volume')
    ->summarize(Sum::make()
        ->prefix('Total volume: ')
        ->suffix(new HtmlString(' m³'))
    )

自定义汇总值

通过从 using() 方法中返回值,你可以创建自定义汇总:

use Filament\Tables\Columns\Summarizers\Summarizer;
use Filament\Tables\Columns\TextColumn;
use Illuminate\Database\Query\Builder;

TextColumn::make('name')
    ->summarize(Summarizer::make()
        ->label('First last name')
        ->using(fn (Builder $query): string => $query->min('last_name')))

回调函数可以访问数据库 $query 构造器实例以执行计算。它返回要在表格中显示的值。

条件性隐藏汇总

要隐藏某个汇总值,你可以传递一个布尔值或者返回布尔值的函数到 hidden() 方法中。如果需要,你可以通过该函数的 $query 参数返回该汇总器的 Eloquent 查询构造器实例:

use Filament\Tables\Columns\Summarizers\Summarizer;
use Filament\Tables\Columns\TextColumn;
use Illuminate\Database\Eloquent\Builder;

TextColumn::make('sku')
    ->summarize(Summarizer::make()
        ->hidden(fn (Builder $query): bool => ! $query->exists()))

此外,你也可以使用 visable() 方法进行反向操作:

use Filament\Tables\Columns\Summarizers\Summarizer;
use Filament\Tables\Columns\TextColumn;
use Illuminate\Database\Eloquent\Builder;

TextColumn::make('sku')
    ->summarize(Summarizer::make()
        ->visible(fn (Builder $query): bool => $query->exists()))

汇总行组

你可以使用分组汇总来显示组内记录的摘要。如果你选择向分组表格的列添加汇总,则此功能会自动工作。

隐藏分组行并仅显示摘要

你可以将行隐藏在分组中,而使用 groupsOnly() 方法只显示每个分组的汇总。这对于许多报告场景中都是有益的。

use Filament\Tables\Columns\Summarizers\Sum;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;

public function table(Table $table): Table
{
    return $table
        ->columns([
            TextColumn::make('views_count')
                ->summarize(Sum::make()),
            TextColumn::make('likes_count')
                ->summarize(Sum::make()),
        ])
        ->defaultGroup('category')
        ->groupsOnly();
}

Hiding summary rows

By default, both the page summary and total summary rows are displayed when columns have summarizers. You can control which summary rows appear using the summaries() method on the table:

use Filament\Tables\Table;

public function table(Table $table): Table
{
    return $table
        ->summaries(
            pageCondition: false,
            allTableCondition: false
        );
}

pageCondition controls whether the “this page” summary row is shown, and allTableCondition controls whether the total summary row for the entire table is shown.

This is useful when using group summaries where you only want to display summaries per group, or when the page summary is redundant and you only need the total across all records.

Edit on GitHub

Still need help? Join our Discord community or open a GitHub discussion

Previous
布局