React Table 添加底部汇总行:CO2/kg 总量示例教程
前言
在数据表格中,除了展示明细数据外,通常还需要对关键指标进行汇总统计。本文将通过一个具体案例,演示如何在 React Table 中为 CO2/kg 列添加底部汇总行,实时计算并显示该列数据的总和。
环境准备
在开始之前,请确保已安装以下依赖:
- react-table:用于构建表格组件
- @tanstack/react-table:React Table v8+ 的核心库
- react:React 框架核心
可通过 npm 安装:
npm install @tanstack/react-table react
实现步骤
1. 定义数据结构与列配置
首先定义表格的数据结构和列配置,重点标记需要汇总的 CO2/kg 列。
import { useMemo } from 'react';
import {
useTable,
useGlobalFilter,
useSortBy,
usePagination
} from '@tanstack/react-table';
// 定义数据类型
const data = [
{ id: 1, product: '产品A', co2PerKg: 12.5 },
{ id: 2, product: '产品B', co2PerKg: 8.3 },
{ id: 3, product: '产品C', co2PerKg: 15.2 },
// ...更多数据
];
// 定义列配置
const columns = [
{
accessorKey: 'product',
header: '产品名称',
},
{
accessorKey: 'co2PerKg',
header: 'CO2/kg',
cell: info => info.getValue().toFixed(2), // 保留两位小数
},
];2. 创建表格组件并添加汇总行
使用 useTable Hook 创建表格实例,并通过 footerGroups 添加汇总行。
function CO2Table() {
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
footerGroups, // 用于访问表脚组
} = useTable(
{
columns,
data,
},
useGlobalFilter,
useSortBy,
usePagination
);
// 计算 CO2/kg 总和
const totalCo2 = useMemo(() => {
return rows.reduce((sum, row) => sum + row.original.co2PerKg, 0);
}, [rows]);
return (
<table {...getTableProps()} style={{ width: '100%', borderCollapse: 'collapse' }}>
{/* 表头 */}
<thead>
{headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => (
<th {...column.getHeaderProps(column.getSortByToggleProps())}>
{column.render('header')}
{/* 排序指示器 */}
<span>
{column.isSorted ? (column.isSortedDesc ? ' ?' : ' ?') : ''}
</span>
</th>
))}
</tr>
))}
</thead>
{/* 表体 */}
<tbody {...getTableBodyProps()}>
{rows.map(row => {
prepareRow(row);
return (
<tr {...row.getRowProps()}>
{row.cells.map(cell => (
<td {...cell.getCellProps()}>{cell.render('Cell')}</td>
))}
</tr>
);
})}
</tbody>
{/* 表脚 - 汇总行 */}
<tfoot>
{footerGroups.map(footerGroup => (
<tr {...footerGroup.getFooterGroupProps()}>
{footerGroup.headers.map(column => {
// 为 CO2/kg 列添加汇总数据
if (column.accessorKey === 'co2PerKg') {
return (
<td {...column.getFooterProps()}>
<strong>总计: {totalCo2.toFixed(2)} kg</strong>
</td>
);
}
// 其他列留空或显示合计标识
return <td {...column.getFooterProps()}></td>;
})}
</tr>
))}
</tfoot>
</table>
);
}3. 优化与扩展
上述基础实现可以进一步优化:
- 格式化显示:添加千位分隔符或单位转换
- 条件样式:根据汇总值大小设置不同颜色
- 动态更新:结合状态管理实现数据变化时自动重新计算
优化后的汇总单元格渲染:
// 在 tfoot 的 td 渲染中添加条件样式
if (column.accessorKey === 'co2PerKg') {
const color = totalCo2 > 100 ? 'red' : totalCo2 > 50 ? 'orange' : 'green';
return (
<td {...column.getFooterProps()}>
<strong style={{ color }}>总计: {totalCo2.toLocaleString('zh-CN', {
minimumFractionDigits: 2,
maximumFractionDigits: 2
})} kg</strong>
</td>
);
}完整示例代码
以下是整合了所有功能的完整组件代码:
import { useMemo } from 'react';
import {
useTable,
useGlobalFilter,
useSortBy,
usePagination
} from '@tanstack/react-table';
function CO2SummaryTable() {
const data = [
{ id: 1, product: '产品A', co2PerKg: 12.5 },
{ id: 2, product: '产品B', co2PerKg: 8.3 },
{ id: 3, product: '产品C', co2PerKg: 15.2 },
{ id: 4, product: '产品D', co2PerKg: 22.7 },
{ id: 5, product: '产品E', co2PerKg: 9.8 },
];
const columns = [
{
accessorKey: 'product',
header: '产品名称',
},
{
accessorKey: 'co2PerKg',
header: 'CO2/kg',
cell: info => info.getValue().toFixed(2),
},
];
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
footerGroups,
} = useTable(
{
columns,
data,
},
useGlobalFilter,
useSortBy,
usePagination
);
const totalCo2 = useMemo(() => {
return rows.reduce((sum, row) => sum + row.original.co2PerKg, 0);
}, [rows]);
return (
<div style={{ padding: '20px' }}>
<h2>产品 CO2 排放量表</h2>
<table {...getTableProps()} style={{ width: '100%', borderCollapse: 'collapse' }}>
<thead>
{headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => (
<th {...column.getHeaderProps(column.getSortByToggleProps())}>
{column.render('header')}
<span>
{column.isSorted ? (column.isSortedDesc ? ' ?' : ' ?') : ''}
</span>
</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.map(row => {
prepareRow(row);
return (
<tr {...row.getRowProps()}>
{row.cells.map(cell => (
<td {...cell.getCellProps()}>{cell.render('Cell')}</td>
))}
</tr>
);
})}
</tbody>
<tfoot>
{footerGroups.map(footerGroup => (
<tr {...footerGroup.getFooterGroupProps()}>
{footerGroup.headers.map(column => {
if (column.accessorKey === 'co2PerKg') {
const color = totalCo2 > 100 ? 'red' : totalCo2 > 50 ? 'orange' : 'green';
return (
<td {...column.getFooterProps()}>
<strong style={{ color }}>总计: {totalCo2.toLocaleString('zh-CN', {
minimumFractionDigits: 2,
maximumFractionDigits: 2
})} kg</strong>
</td>
);
}
return <td {...column.getFooterProps()}></td>;
})}
</tr>
))}
</tfoot>
</table>
</div>
);
}
export default CO2SummaryTable;总结
通过 React Table 的 footerGroups 和 useMemo Hook,我们可以轻松实现表格底部汇总行的功能。这种方法不仅适用于 CO2/kg 总量的计算,还可以扩展到其他数值列的统计分析。关键在于合理利用表格的生命周期钩子和数据计算函数,确保汇总数据的准确性和实时性。
在实际项目中,还可以结合后端 API 获取汇总数据,或通过更复杂的计算逻辑实现多维度的数据分析展示。