关于 syncfusion-flutter-datagrid
用于在 Flutter 应用中实现和定制 Syncfusion Flutter DataGrid 的技能,涵盖数据处理、表格交互、大型数据集、无障碍功能与导出。
主要功能
- 01绑定 List 和 ObservableList 数据
- 02配置并设置表格列样式
- 03编辑、排序、筛选和分组数据
- 04汇总、分页与虚拟化
- 05将数据导出为 Excel 和 PDF
适用场景
- 01展示和浏览应用中的表格数据
- 02构建可编辑的数据录入表格
- 03通过分组汇总分析数据
- 04将表格内容导出为 Excel 或 PDF
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ syncfusion/ flutter-ui-components-skills --skill syncfusion-flutter-datagrid安装后在 Claude Code 中输入/syncfusion-flutter-datagrid确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/accessibility.mdcolumn-drag-and-drop.mdcolumn-resizing.mdcolumn-sizing.mdcolumn-types.mdconditional-styling.mddata-binding.mdediting.mdexport-to-excel.mdexport-to-pdf.mdfiltering.mdfooter.mdfreeze-panes.mdgetting-started.mdgrouping.mdload-more.mdlocalization.mdpaging.mdplaceholder.mdpull-to-refresh.mdright-to-left.mdrow-height-customization.mdscrolling.mdselection.mdsorting.mdstacked-headers.mdstyles.mdsummaries.mdswiping.md详细介绍
实现 Syncfusion Flutter DataGrid
一项全面的技能,用于实现和自定义 Syncfusion Flutter DataGrid(SfDataGrid)控件。DataGrid 以表格形式显示和操作数据,支持列、编辑、排序、筛选、分组、汇总、分页和导出功能。
何时使用此技能
在以下情况下使用此技能:
- 在 Flutter 应用中显示表格数据
- 将数据源(List、ObservableList)绑定到网格
- 配置列(自动生成或手动定义)
- 实现单元格编辑和样式设置
- 添加排序、筛选或搜索功能
- 对数据分组并显示汇总/聚合结果
- 实现分页或增量加载
- 启用行操作(拖放、滑动、添加/删除)
- 将网格数据导出为 Excel 或 PDF
- 自定义网格外观和行为
- 优化大型数据集的性能
- 处理键盘导航和无障碍功能
组件概览
Syncfusion Flutter DataGrid(SfDataGrid)是一个高性能数据网格控件,用于在 Flutter 应用中显示和操作表格数据。它支持全面的数据管理功能,包括排序、筛选、分组和汇总。该网格具有高度可自定义性,并针对小型和大型数据集进行了优化,支持高效的虚拟化和分页。
SfDataGrid 擅长:
- 以行和列的形式显示结构化数据
- 通过排序和筛选交互式探索数据
- 通过分组和汇总进行复杂的数据分析
- 通过虚拟化和分页处理大型数据集
- 通过单元格内编辑进行数据录入和验证
- 将数据导出为 Excel 和 PDF 格式
- 构建响应式、数据驱动的仪表板和报告
主要功能
- 数据绑定选项: 支持 List 和 ObservableList 数据源
- 灵活的列配置: 支持手动定义列
- 单元格内编辑: 编辑单元格内容,并进行验证和使用自定义编辑器
- 高级排序: 支持单列和多列排序,并可使用自定义逻辑
- 强大的筛选功能: 提供内置筛选和自定义筛选谓词
- 数据分组: 按一个或多个列对数据分组,并支持展开/折叠
- 汇总聚合: 提供分组汇总和标题汇总,并内置函数
- 选择模式: 支持单选、多选或不选择,并提供事件回退机制
- 分页和虚拟化: 通过数据虚拟化高效处理大型数据集
- 导出功能: 可导出为 Excel(.xlsx)和 PDF 格式,并支持自定义
- 行操作: 支持滑动操作、拖放和动态行高
- 冻结支持: 冻结列和行,方便导航
- 全面的样式设置: 支持单元格、行和标题样式,以及条件格式
- 无障碍功能: 支持键盘导航和屏幕阅读器
文档和导航指南
开始使用
📄 阅读: references/getting-started.md
- 安装和 pub 包设置
- 在 pubspec.yaml 中添加依赖
- 导入 datagrid 包
- 创建首个 datagrid
- 最小可运行示例
数据绑定
📄 阅读: references/data-binding.md
- 基本 DataGrid 实现
- 创建数据模型和 DataGridSource
- 使用 List 和 ObservableList 绑定数据
列类型
📄 阅读: references/column-types.md
- 手动定义列
- 列属性(columnName、label、width)
- 列尺寸和宽度选项
- 列的可见性和排序
- 复选框列及其自定义
- 标题图标可见性
列尺寸
📄 阅读: references/column-sizing.md
- 列宽配置模式
- 自动适应和填充模式
- 手动调整列宽
- 宽度计算策略
- 动态调整宽度
列宽调整
📄 阅读: references/column-resizing.md
- 启用/禁用列宽调整
- 调整交互与用户体验
- 通过编程方式调整列宽
- 调整事件与回调
- 自动适应列宽
列拖放
📄 阅读: references/column-drag-and-drop.md
- 启用拖放以重新排序列
- 列重新排序事件
- 通过编程方式重新排序列
- 拖放限制与行为
多层表头
📄 阅读: references/stacked-headers.md
- 多级列标题
- 多层表头配置
- 跨表头合并列
- 表头自定义与样式设置
冻结窗格
📄 阅读: references/freeze-panes.md
- 冻结列(左侧)
- 冻结行(顶部)
- 冻结窗格配置
- 冻结窗格中的滚动
滚动
📄 阅读: references/scrolling.md
- 水平和垂直滚动
- 自定义滚动行为
- 通过编程方式滚动
- 滚动事件与回调
- 虚拟滚动性能
编辑
📄 阅读: references/editing.md
- 启用编辑
- 列级编辑控制
- 编辑触发方式与模式
- 单元格编辑事件(onBeginEdit、onEndEdit)
- 通过编程方式编辑
- 编辑时使用 Enter、方向键和 Tab 键导航
排序
📄 阅读: references/sorting.md
- 单列和多列排序
- 自定义排序逻辑
- 通过编程方式排序
- 排序图标与 UI 自定义
- 排序顺序行为
筛选
📄 阅读: references/filtering.md
- 筛选功能基础
- 筛选类型与谓词
- 通过编程方式筛选
- 自定义筛选逻辑
- 筛选 UI 自定义
选择
📄 阅读: references/selection.md
- 选择模式(Single、Multiple、None)
- 选择事件(onSelectionChanging、onSelectionChanged)
- 通过编程方式选择
- 当前单元格与选中行的区别
分组
📄 阅读: references/grouping.md
- 数据分组(单列和多列)
- 分组展开/折叠行为
- 自定义分组逻辑
- 分组标题自定义
汇总
📄 阅读: references/summaries.md
- 汇总行(分组汇总和标题汇总)
- 内置聚合函数(Sum、Average、Count、Min、Max)
- 自定义汇总计算
- 汇总显示格式
- 汇总页脚配置
分页
📄 阅读: references/paging.md
- 分页设置与配置
- 每页条数与页面导航
- 自定义分页 UI
- 通过编程方式切换页面
- 页面更改事件
加载更多
📄 阅读: references/load-more.md
- 增量加载设置
- 加载更多行的处理
- 加载更多的触发方式与事件
- 通过编程方式控制加载更多
- 大型数据集的分页策略
下拉刷新
📄 阅读: references/pull-to-refresh.md
- 下拉刷新手势
- 刷新事件处理
- 自定义刷新 UI
- 加载状态管理
- 数据刷新模式
自定义行高
📄 阅读: references/row-height-customization.md
- 行高配置
- 根据内容自动调整行高
- QueryRowHeight 事件的用法
- 动态调整行高
- 自定义表头行高
滑动操作
📄 阅读: references/swiping.md
- 行滑动手势
- 滑动操作与命令
- 滑动事件处理
- 自定义滑动操作 UI
- 滑动范围配置
样式
📄 阅读: references/styles.md
- 网格样式基础
- 单元格样式(DataGridCellStyle)
- 条件单元格样式
- 行样式与交替行颜色
- 表头样式
- 主题自定义
条件样式
📄 阅读: references/conditional-styling.md
- 根据单元格/行数据应用样式
- 动态样式逻辑
- 样式构建器和回调
- 条件样式的性能优化
占位内容
📄 阅读: references/placeholder.md
- 空 DataGrid 视图
- 自定义占位组件
- 加载状态显示
- 自定义无数据提示
导出到 Excel
📄 阅读: references/export-to-excel.md
- 将 DataGrid 导出到 Excel
- 自定义 Excel 导出(列、行、样式)
- Excel 导出选项和事件
- 文件保存与分享
导出到 PDF
📄 阅读: references/export-to-pdf.md
- 将 DataGrid 导出到 PDF
- 自定义 PDF 导出
- 页面方向和尺寸
- PDF 导出事件
- 文件保存与分享
页脚
📄 阅读: references/footer.md
- 配置页脚行
- 在页脚中显示汇总信息
- 自定义页脚内容
- 页脚样式
无障碍
📄 阅读: references/accessibility.md
- 键盘导航
- 屏幕阅读器支持
- 无障碍最佳实践
本地化
📄 阅读: references/localization.md
- 本地化设置
- 多语言支持
从右到左
📄 阅读: references/right-to-left.md
- RTL(从右到左)支持
- 自定义文本方向
快速入门示例
步骤 1:添加包
# Always installs the latest compatible version automatically
flutter pub add syncfusion_flutter_datagrid
始终通过终端安装包,不要直接编辑
pubspec.yaml。 在 Flutter 项目根目录运行此命令,并等待其成功完成后再继续。
步骤 2:创建数据模型
class OrderInfo {
int orderId;
String customerId;
String shipCountry;
double freight;
DateTime orderDate;
OrderInfo({
required this.orderId,
required this.customerId,
required this.shipCountry,
required this.freight,
required this.orderDate,
});
}
步骤 3:创建 DataGridSource
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
class OrderDataSource extends DataGridSource {
late List<OrderInfo> _orders;
OrderDataSource(List<OrderInfo> orders) {
_orders = orders;
buildDataGridRows();
}
List<DataGridRow> dataGridRows = [];
@override
List<DataGridRow> get rows => dataGridRows;
void buildDataGridRows() {
dataGridRows = _orders
.map<DataGridRow>((order) => DataGridRow(cells: [
DataGridCell<int>(columnName: 'orderId', value: order.orderId),
DataGridCell<String>(columnName: 'customerId', value: order.customerId),
DataGridCell<String>(columnName: 'shipCountry', value: order.shipCountry),
DataGridCell<double>(columnName: 'freight', value: order.freight),
DataGridCell<DateTime>(columnName: 'orderDate', value: order.orderDate),
]))
.toList();
}
@override
DataGridRowAdapter? buildRow(DataGridRow row) {
return DataGridRowAdapter(cells: [
Container(
alignment: Alignment.centerRight,
padding: const EdgeInsets.all(8.0),
child: Text(row.getCells()[0].value.toString()),
),
Container(
alignment: Alignment.centerLeft,
padding: const EdgeInsets.all(8.0),
child: Text(row.getCells()[1].value.toString()),
),
Container(
alignment: Alignment.centerLeft,
padding: const EdgeInsets.all(8.0),
child: Text(row.getCells()[2].value.toString()),
),
Container(
alignment: Alignment.centerRight,
padding: const EdgeInsets.all(8.0),
child: Text('\$${row.getCells()[3].value.toStringAsFixed(2)}'),
),
Container(
alignment: Alignment.centerLeft,
padding: const EdgeInsets.all(8.0),
child: Text(row.getCells()[4].value.toString().split(' ')[0]),
),
]);
}
}
步骤 4:将 DataGrid 添加到视图
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
class DataGridPage extends StatefulWidget {
const DataGridPage({Key? key}) : super(key: key);
@override
State<DataGridPage> createState() => _DataGridPageState();
}
class _DataGridPageState extends State<DataGridPage> {
late List<OrderInfo> _orders;
late OrderDataSource _orderDataSource;
@override
void initState() {
super.initState();
_orders = getOrders();
_orderDataSource = OrderDataSource(_orders);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('DataGrid'),
),
body: SfDataGrid(
source: _orderDataSource,
columns: [
GridColumn(
columnName: 'orderId',
label: Container(
padding: const EdgeInsets.all(16.0),
alignment: Alignment.centerRight,
child: const Text('Order ID'),
),
),
GridColumn(
columnName: 'customerId',
label: Container(
padding: const EdgeInsets.all(16.0),
alignment: Alignment.centerLeft,
child: const Text('Customer Name'),
),
),
GridColumn(
columnName: 'shipCountry',
label: Container(
padding: const EdgeInsets.all(16.0),
alignment: Alignment.centerLeft,
child: const Text('Ship Country'),
),
),
GridColumn(
columnName: 'freight',
label: Container(
padding: const EdgeInsets.all(16.0),
alignment: Alignment.centerRight,
child: const Text('Freight'),
),
),
GridColumn(
columnName: 'orderDate',
label: Container(
padding: const EdgeInsets.all(16.0),
alignment: Alignment.centerLeft,
child: const Text('Order Date'),
),
),
],
),
);
}
List<OrderInfo> getOrders() {
return [
OrderInfo(
orderId: 1001,
customerId: 'ALFKI',
shipCountry: 'Germany',
freight: 32.38,
orderDate: DateTime(2024, 01, 15),
),
OrderInfo(
orderId: 1002,
customerId: 'FRANS',
shipCountry: 'Mexico',
freight: 11.61,
orderDate: DateTime(2024, 01, 14),
),
OrderInfo(
orderId: 1003,
customerId: 'MEREP',
shipCountry: 'Canada',
freight: 45.34,
orderDate: DateTime(2024, 01, 13),
),
];
}
}
主要属性和配置
| 属性 | 类型 | 描述 |
|---|---|---|
source | DataGridSource | 网格的数据源(必需) |
columns | List | 列定义(必需) |
rowHeight | double | 默认行高 |
headerRowHeight | double | 表头行高 |
allowSorting | bool | 启用排序 |
allowMultiColumnSorting | bool | 启用多列排序 |
allowFiltering | bool | 启用筛选 |
allowEditing | bool | 启用单元格编辑 |
navigationMode | GridNavigationMode | 行导航或单元格导航 |
selectionMode | SelectionMode | 无、单选或多选 |
frozenColumnsCount | int | 从左侧开始冻结的列数 |
frozenRowsCount | int | 从顶部开始冻结的行数 |
columnWidthMode | ColumnWidthMode | 自动、填充、无 |
常见模式
模式 1:支持多列的排序
启用单列和多列排序,并显示视觉指示器:
SfDataGrid(
source: _employeeDataSource,
allowSorting: true,
allowMultiColumnSorting: true,
allowTriStateSorting: true,
showSortNumbers: true,
columns: _columns,
)
添加程序化排序:
_employeeDataSource.sortedColumns.add(
SortColumnDetails(
name: 'name',
sortDirection: DataGridSortDirection.ascending,
),
);
_employeeDataSource.sort();
模式 2:支持程序化和 UI 操作的筛选
启用程序化筛选和基于 UI 的筛选:
SfDataGrid(
source: _employeeDataSource,
allowFiltering: true,
columns: _columns,
onFilterChanging: (DataGridFilterChangeDetails details) {
// Optional: validate before applying filter
return true;
},
onFilterChanged: (DataGridFilterChangeDetails details) {
// Optional: handle post-filter notification
print('Filtered column: ${details.column.columnName}');
},
)
添加程序化筛选器:
// Add single condition
_employeeDataSource.addFilter(
'salary',
FilterCondition(
type: FilterType.greaterThanOrEqual,
value: 50000,
),
);
// Add multiple conditions (AND operator)
_employeeDataSource.addFilter(
'salary',
FilterCondition(
value: 100000,
type: FilterType.lessThanOrEqual,
filterOperator: FilterOperator.and,
),
);
// Clear filters
_employeeDataSource.clearFilters('salary');
模式 3:使用自定义标题和展开/折叠进行分组
实现分层数据分组及展开/折叠功能:
// In initState
_employeeDataSource.addColumnGroup(
ColumnGroup(name: 'city', sortGroupRows: true),
);
// In widget build
SfDataGrid(
source: _employeeDataSource,
controller: _dataGridController,
allowExpandCollapseGroup: true,
autoExpandGroups: false,
groupCaptionTitleFormat: '{ColumnName}: {Key} ({ItemsCount} records)',
groupExpanded: (DataGridGroupChangedDetails group) {
print('Group expanded: ${group.key}');
},
groupCollapsed: (DataGridGroupChangedDetails group) {
print('Group collapsed: ${group.key}');
},
columns: _columns,
)
程序化展开/折叠:
// Expand all groups
_dataGridController.expandAllGroup();
// Collapse groups at specific level
_dataGridController.collapseGroupsAtLevel(1);
常见用例
| 用例 | 主要功能 | 参考文件 |
|---|---|---|
| 基本数据展示 | 数据绑定、列 | getting-started.md、column-types.md |
| 可编辑网格 | 单元格编辑、验证 | editing.md、data-binding.md |
| 可排序/筛选的表格 | 排序、筛选 | sorting.md、filtering.md |
| 带汇总值的分组数据 | 分组、汇总 | grouping.md、summaries.md |
| 大型数据集 | 分页、加载更多 | paging.md、load-more.md |
| 数据导出 | 导出为 Excel/PDF | export-to-excel.md、export-to-pdf.md |
| 响应式布局 | 列尺寸、滚动 | column-sizing.md、scrolling.md |
| 自定义单元格布局 | 模板、样式 | styles.md、conditional-styling.md |
故障排除
DataGrid 未显示数据:
- 确认已将有效的 DataGridSource 赋给
source - 检查是否已定义
columns - 确保在 DataGridSource 构造函数中调用了
buildDataGridRows() - 确认数据模型不为空
编辑无法使用:
- 设置
allowEditing=true - 将
navigationMode设置为GridNavigationMode.cell - 将
selectionMode设置为 Single 或 Multiple - 检查列的
allowEditing属性
排序无法使用:
- 在 SfDataGrid 上启用
allowSorting=true - 确认列标题可点击(检查
GridColumn.allowSorting不为false) - 如果使用自定义排序,检查 DataGridSource 中是否正确实现了自定义
compare()方法 - 对于异步排序,在 DataGridSource 中重写
performSorting()
筛选无法使用:
- 在 SfDataGrid 上启用
allowFiltering=true - 确认列标题上显示了筛选图标(检查
GridColumn.allowFiltering不为false) - 对于程序化筛选,确保
addFilter()中的列名与GridColumn.columnName完全匹配 - 检查
FilterCondition.type是否适用于该数据类型 - 确认
effectiveRows返回筛选后的结果;使用clearFilters()重置所有筛选条件
未显示分组:
- 确保在构建网格前调用了
addColumnGroup() - 确认
ColumnGroup.name与某个GridColumn.columnName完全匹配 - 检查分组列是否包含非空值
- 启用
allowExpandCollapseGroup=true以显示展开/折叠界面 - 使用
DataGridController和expandAllGroup()确认分组是否正常工作
多列排序无法使用:
- 在 SfDataGrid 上设置
allowMultiColumnSorting=true - 对于 Web/桌面端:按住 Ctrl 并点击列标题,以添加其他排序列
- 检查
sortedColumns列表,确认其中存在多个排序条目 - 以编程方式修改
sortedColumns后调用sort()
自定义分组逻辑未生效:
- 在 DataGridSource 中重写
performGrouping() - 将自定义分组键作为 String 返回
- 确保该方法返回非空值,以便正确分组
后续步骤
- 从 references/getting-started.md 开始进行基本设置
- 使用 references/column-types.md 配置列
- 通过编辑、排序和筛选添加交互功能
- 根据数据规模使用分页或虚拟化进行优化
- 使用样式和模板自定义外观