Skip to content
全部文档

汇总

简介

你可以在表格内容下方渲染「汇总」(summary)区域。这对展示平均值、总和、计数和范围等计算结果很有用。

默认情况下,会有一行针对当前页数据的汇总,若存在多页,还会有一行针对全部数据总计的汇总。你也可以为记录的分组添加汇总,参见「汇总分组行」

「汇总器」(Summarizer)对象可通过 summarize() 方法添加到任意表格列

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

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

同一列可添加多个「汇总器」:

php
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(),
    ])
表格的第一列不能使用汇总器。该列用于渲染汇总区域的标题和副标题。
带汇总的表格带汇总的表格

可用汇总器

Filament 内置四种汇总器:

  • [平均值(Average)](#average)
  • [计数(Count)](#count)
  • [范围(Range)](#range)
  • [求和(Sum)](#sum)

你也可以创建自定义汇总器,以任意方式展示数据。

平均值

Average 可用于计算数据集中所有值的平均值:

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

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

在本例中,表格中的所有评分会相加,再除以评分数量。

带平均值汇总的表格带平均值汇总的表格

计数

Count 可用于计算数据集中值的总数。除非你只想计算行数,否则通常还需要限定数据集作用域

php
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)),
    ),

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

统计图标出现次数

图标列上使用 count 时,可以使用 icons() 方法,以可视化方式展示表格中每种图标的数量:

php
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()),
带图标计数汇总的表格带图标计数汇总的表格

范围

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

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

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

在本例中,会找出表格中的最低价和最高价。

带范围汇总的表格带范围汇总的表格

日期范围

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

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

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

该方法会呈现最小日期与最大日期之间的最小差异。例如:

  • 若最小与最大日期不在同一天,则仅显示日期。
  • 若最小与最大日期在同一天但时间不同,则同时显示日期和时间。
  • 若最小与最大日期时间完全相同,则只显示一次。

文本范围

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

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

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

该方法会呈现最小值与最大值之间的最小差异。例如:

  • 若最小值与最大值以不同字母开头,则仅显示首字母。
  • 若最小值与最大值以相同字母开头,则会渲染更多文本直到发现差异。
  • 若最小值与最大值完全相同,则只显示一次。

在范围中包含 null 值

默认情况下,范围会排除 null 值。若希望包含它们,可以使用 excludeNull(false) 方法:

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

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

求和

Sum 可用于计算数据集中所有值的总和:

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

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

在本例中,表格中的所有价格会相加。

带求和汇总的表格带求和汇总的表格

设置标签

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

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

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

隐藏汇总器标签

将标签设为空字符串以隐藏它或许很诱人,但不建议这样做。将标签设为空字符串无法向屏幕阅读器传达汇总器的用途,即使视觉上用途很明确。你应改用 hiddenLabel() 方法,使其在视觉上隐藏但对屏幕阅读器仍可访问:

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

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

你也可以有条件地隐藏标签:

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

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

限定数据集作用域

你可以使用 query() 方法为汇总器的数据集应用数据库查询作用域:

php
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_publishedtrue 的行会用于计算平均值。

此功能与 count 汇总器尤其搭配得好,因为它可以统计数据集中有多少记录通过某项测试:

php
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() 方法可将条目格式化为数字:

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

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

若要自定义格式化数字时使用的小数位数,可以使用 decimalPlaces 参数:

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

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

默认情况下,会使用应用的 locale 适当地格式化数字。若要自定义所用 locale,可将其传给 locale 参数:

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

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

货币格式化

money() 方法可轻松将金额格式化为任意货币:

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

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

money() 还有一个 divideBy 参数,可在格式化前将原始值除以某个数。例如,若数据库以分为单位存储价格,这会很有用:

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

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

默认情况下,会使用应用的 locale 适当地格式化金额。若要自定义所用 locale,可将其传给 locale 参数:

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

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

若要自定义格式化数字时使用的小数位数,可以使用 decimalPlaces 参数:

php
use Filament\Tables\Columns\TextColumn;

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

限制文本长度

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

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

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

添加前缀或后缀

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

php
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() 方法返回值来创建自定义汇总:

php
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 查询构建器实例:

php
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()))

或者,你可以使用 visible() 方法实现相反效果:

php
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() 方法隐藏分组内的行,仅显示每个分组的汇总。这在许多报表场景中很有用。

php
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();
}

隐藏汇总行

默认情况下,当列有汇总器时会同时显示页面汇总行和总计汇总行。你可以使用表格上的 summaries() 方法控制显示哪些汇总行:

php
use Filament\Tables\Table;

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

pageCondition 控制是否显示「本页」汇总行,allTableCondition 控制是否显示整张表的总计汇总行。

这在使用分组汇总且只想按分组显示汇总时很有用,或在页面汇总多余、只需要全部记录总计时也很有用。