Flutter数据处理与表格展示插件data_sheet的使用

Flutter数据处理与表格展示插件data_sheet的使用

描述

我在寻找一个允许固定表头/列、现场编辑、锁定单元格等功能的组件,并且能够处理大量数据。

经过搜索,我发现horizontal_data_table,但仍然不能满足我的需求;所以我决定自己开发。

这个包就是这个想法的结果。希望你会觉得它有用。欢迎评论和贡献来改进这个包。

性能

我已经在安卓手机和网页上测试了2048行x512列的数据,没有发现任何性能问题。

特性

  • 快速且轻量级的组件
  • 可以固定顶部行和左侧列,使其始终可见
  • 现场编辑
  • 编辑完成后自动滚动到下一个单元格
  • 下拉建议
  • 可调整列宽
  • 行列装饰/样式
  • 选择/取消选择单元格/行
  • 允许自定义小部件作为单元格内容

安装

安装data_table

flutter pub add data_table

示例

示例演示

固定列宽

像素宽度

比例宽度

滚动

排序

选择

使用示例

参数设置

List<CellSetup> _cellSetups = [
  CellSetup(selected:_selected),
  CellSetup(
      textInputType:TextInputType.name, 
      defaultSort: EditAction.sortA2Z, selected:_selected),
  CellSetup(
      suggestions:_suggestGender, 
      action:SuggestionsAction.restrict,
      defaultSort: EditAction.sortNone),
  CellSetup(
      suggestions:_suggestCountry,     
      textInputType:TextInputType.name, 
      defaultSort: EditAction.sortZ2A, 
      triStateSort:false),
  CellSetup(                          
      suggestions:_suggestFood,     
      getWidget: _getCustomeCellWidget,
      action:SuggestionsAction.keep,  
      textInputType:TextInputType.name),
  CellSetup(textInputType:TextInputType.number),
];

主要组件

DataTable(
    data:_data,                         // 数据列表
    onUpdate: onUpdate,                 // 回调函数
    onSelectCell:onSelectCell,          // 回调函数
    cellSetups:_cellSetups,             // 单元格配置列表

    isEditing: true,                    // 是否可编辑

    outerController: outerController,   // 外部控制器
    outerPhysics: outerPhysics,         // 外部滚动属性

    pinnedRows: _pinnedRows,            // 固定的顶部行数
    pinnedCols: _pinnedCols,            // 固定的左侧列数

    cellSize: const Size(100,kToolbarHeight*0.7),

    columnWidths:const [0.15,0.3,0.2,0.2,0.2, 0.2],
    columnWidthOption: ColumnWidthOption.ratio,
    
    decoPinnedRow: [                    // 固定行的装饰
                    _decoPinnedRow1,
                    _decoPinnedRow2,
                    ],
    decoPinnedCol: [ _decoPinnedCol1,], // 固定列的装饰
    decoNormal: _decoNormalCell,        // 普通单元格的装饰
    stylePinnedRowText: 
        _stylePinnedRowText,    // 固定行文本样式
    stylePinnedColText: 
        _stylePinnedColText,    // 固定列文本样式
    styleNormalCellText: 
        _styleNormalCellText,  // 普通单元格文本样式
);

参数说明

data

包含所有列和行的字符串值。用户需要将所有值转换为字符串并最终生成List<List<String>>

/// 样例:将Friends类转换为[data]
    _bodyPage3 = _friends.map((e) {
      return [
        '${e.id}',
        e.name,
        e.gender,
        e.country,
        e.food,
        DateFormat('dd-MMM-yyyy')
            .format(DateTime.fromMillisecondsSinceEpoch(e.dobEpoch)),
        e.weight.toStringAsFixed(1),
        e.height.toStringAsFixed(1)
      ];
    }).toList();

onUpdate

这是主要的回调函数,当用户执行编辑或排序操作时,该组件会调用此函数。该函数传递一个与单元格相关的动态值,包括行和列号以及采取的动作。用户有责任处理传入的值并进行更新。

bool onUpdate(int row, int col, dynamic value, EditAction action) {
  late String str, newValue;
  double? val;
  int count = 0;

  str = '';
  switch (action) {
    case EditAction.add:
      List<String> nl = List.generate(_header1.length, (index) {
        return index == 0 ? '${_dataPage3.length - _pinnedRows + 1}.' : '';
      });
      ...
      ...
      break;
    case EditAction.delete:
      int rowNo = _curRow - _pinnedRows;
      setState(() {
        _bodyPage3.removeAt(rowNo);
        _selected.removeAt(rowNo);
        if (_curRow >= _bodyPage3.length + _pinnedRows) _curRow--;
        for (int i = rowNo; i < _bodyPage3.length; i++) {
          _bodyPage3[i][0] = '${i - _pinnedRows + 1}.';
        }
      });
      break;
    case EditAction.sortNone:
      _bodyPage3.sort((a, b) => a[0].compareTo(b[0]));
      break;
    case EditAction.sortA2Z:
      _bodyPage3.sort((a, b) => a[col].compareTo(b[col]));
      break;
    case EditAction.sortZ2A:
      _bodyPage3.sort((b, a) => a[col].compareTo(b[col]));
      break;
    case EditAction.select:
      _selected[row] = value;
      ...
      ...
      break;
    case EditAction.selectAll:
      ...
      ...
      break;
    default:
      break;
  }
  
  ...
  ...

  switch (col) {
    case 1: // 名字
    case 3: // 国家
    case 4: // 食物
      newValue = value;
      break;
    case 2: // 性别
      newValue = value.substring(0, 1).toUpperCase();
      break;
    case 5: // 生日
      try {
        newValue = DateFormat('dd-MMM-yyyy').format(value);
      } catch (fe) {
        str = fe.toString();
      }
      break;
    case 6: // 体重
    case 7: // 身高
      val = double.tryParse(value);
      if (val != null) {
        newValue = val.toStringAsFixed(1);
      } else {
        str = "输入必须是数字";
      }
      break;

    default:
      assert(false);
      break;
  }
  if (str.isNotEmpty) {
    ...
    /// 报告错误
  } else {
    setState(() {
      _dataPage3[row][col] = newValue;
    });
  }

  return str.isEmpty;
}

更多关于Flutter数据处理与表格展示插件data_sheet的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter数据处理与表格展示插件data_sheet的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter中使用data_sheet插件进行数据处理与表格展示的示例代码。data_sheet插件可以帮助你以表格形式展示数据,并提供一些基本的数据处理功能。请注意,这个插件的具体功能和API可能会随着版本的更新而变化,所以请确保你查阅了最新的文档。

首先,你需要在pubspec.yaml文件中添加data_sheet依赖:

dependencies:
  flutter:
    sdk: flutter
  data_sheet: ^最新版本号  # 请替换为实际的最新版本号

然后,运行flutter pub get来获取依赖。

接下来,在你的Flutter项目中,你可以使用以下代码来展示如何使用data_sheet进行数据处理与表格展示:

import 'package:flutter/material.dart';
import 'package:data_sheet/data_sheet.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter DataSheet Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: DataSheetExample(),
    );
  }
}

class DataSheetExample extends StatefulWidget {
  @override
  _DataSheetExampleState createState() => _DataSheetExampleState();
}

class _DataSheetExampleState extends State<DataSheetExample> {
  List<List<dynamic>> data = [
    ['ID', 'Name', 'Age', 'Email'],
    [1, 'Alice', 24, 'alice@example.com'],
    [2, 'Bob', 30, 'bob@example.com'],
    [3, 'Charlie', 29, 'charlie@example.com'],
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('DataSheet Example'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: DataSheet(
          data: data,
          headerStyle: DataSheetCellStyle(
            backgroundColor: Colors.grey[300],
            fontWeight: FontWeight.bold,
          ),
          cellStyle: DataSheetCellStyle(
            textAlign: TextAlign.left,
          ),
          onCellTap: (rowIndex, colIndex) {
            // 处理单元格点击事件
            print('Tapped on row $rowIndex, column $colIndex: ${data[rowIndex][colIndex]}');
          },
          onRowTap: (rowIndex) {
            // 处理行点击事件
            print('Tapped on row $rowIndex: ${data[rowIndex]}');
          },
          onHeaderTap: (colIndex) {
            // 处理表头点击事件,可以用来排序
            setState(() {
              data.sort((a, b) => a[colIndex].toString().compareTo(b[colIndex].toString()));
            });
          },
        ),
      ),
    );
  }
}

在这个示例中,我们创建了一个简单的Flutter应用,其中包含一个DataSheet组件。这个组件接受一个二维列表作为数据源,并展示为表格。我们还设置了一些样式,比如表头和单元格的样式,并添加了点击事件处理函数。

  • data:二维列表,包含表格的数据。
  • headerStyle:表头的样式。
  • cellStyle:单元格的样式。
  • onCellTap:单元格点击事件处理函数。
  • onRowTap:行点击事件处理函数。
  • onHeaderTap:表头点击事件处理函数,可以用来对数据进行排序。

这个示例展示了如何使用data_sheet插件来创建和展示一个表格,并进行一些基本的数据处理。你可以根据自己的需求进一步定制和扩展这个示例。

回到顶部