mcpField
S
syncfusion-flutter-datagrid

syncfusion-flutter-datagrid

github.com/syncfusion开发255 次安装17 周前更新
代码仓库

关于 syncfusion-flutter-datagrid

用于在 Flutter 应用中实现和定制 Syncfusion Flutter DataGrid 的技能,涵盖数据处理、表格交互、大型数据集、无障碍功能与导出。

主要功能

  1. 01绑定 List 和 ObservableList 数据
  2. 02配置并设置表格列样式
  3. 03编辑、排序、筛选和分组数据
  4. 04汇总、分页与虚拟化
  5. 05将数据导出为 Excel 和 PDF

适用场景

  1. 01展示和浏览应用中的表格数据
  2. 02构建可编辑的数据录入表格
  3. 03通过分组汇总分析数据
  4. 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.md
column-drag-and-drop.md
column-resizing.md
column-sizing.md
column-types.md
conditional-styling.md
data-binding.md
editing.md
export-to-excel.md
export-to-pdf.md
filtering.md
footer.md
freeze-panes.md
getting-started.md
grouping.md
load-more.md
localization.md
paging.md
placeholder.md
pull-to-refresh.md
right-to-left.md
row-height-customization.md
scrolling.md
selection.md
sorting.md
stacked-headers.md
styles.md
summaries.md
swiping.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),
      ),
    ];
  }
}

主要属性和配置

属性类型描述
sourceDataGridSource网格的数据源(必需)
columnsList列定义(必需)
rowHeightdouble默认行高
headerRowHeightdouble表头行高
allowSortingbool启用排序
allowMultiColumnSortingbool启用多列排序
allowFilteringbool启用筛选
allowEditingbool启用单元格编辑
navigationModeGridNavigationMode行导航或单元格导航
selectionModeSelectionMode无、单选或多选
frozenColumnsCountint从左侧开始冻结的列数
frozenRowsCountint从顶部开始冻结的行数
columnWidthModeColumnWidthMode自动、填充、无

常见模式

模式 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/PDFexport-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 返回
  • 确保该方法返回非空值,以便正确分组

后续步骤

  1. 从 references/getting-started.md 开始进行基本设置
  2. 使用 references/column-types.md 配置列
  3. 通过编辑、排序和筛选添加交互功能
  4. 根据数据规模使用分页或虚拟化进行优化
  5. 使用样式和模板自定义外观

评论

支持 Markdown