Flutter表格生成插件dart_tabulate的使用

Flutter表格生成插件dart_tabulate的使用

表格生成插件dart_tabulate的使用

Fun table maker for Dart language
Tabulate 是一个用于在终端生成美观嵌套表格的 Dart 库。

tabulate logo

license version

目录

描述

tabulate 帮助那些想要在终端轻松创建美观且高度可定制表格的人。

注意 Tabulate 支持 Dart >=2.17.5

快速入门只需创建一个 Table 对象并调用 Table.addRows 添加行到表中即可享受它。

import 'package:tabulate/tabulate.dart';

void main() {
  Table table = Table();
  table.addRow(["No.", "Full Name", "Position", "Salary"]);
  table.addRow(["1", "Bill Gates", "Founder Microsoft", "\$1000"]);
  table.addRow(["2", "Steve Jobs", "Founder Apple", "\$1200"]);
  table.addRow(["3", "Larry Page", "Founder Google", "\$1100"]);
  table.addRow(["4", "Mark Zuckerberg", "Founder Facebook", "\$1300"]);
}

可以通过使用 Table.theme 获取器来设置表格样式,该获取器返回一个 TableTheme 对象,然后可以更改表格的属性,例如边框、文本样式、颜色等。

table.theme
  .setBorderColor(Color.red)
  .setFontColor(Color.cyan);

可以通过 Table[rowIndex]Table.rowAt(rowIndex) 访问表中的行。这将返回一个 Row 对象,您可以类似地使用获取器 Row.theme 来设置该行所有单元格的属性。

现在让我们样式化表头。以下代码将改变单元格的字体颜色为 蓝色,将行内容对齐到 居中,应用字体样式为 粗体,更改顶部边框字符为 = 并在行内容的顶部和底部添加填充。

table[0].theme
  .setFontColor(Color.blue)
  .setTextAlign(TextAlign.center)
  .setFontStyle({FontStyle.bold})
  .setBorderTop("=")
  .setPaddingTop(1)
  .setPaddingBottom(1);

也可以通过 Table.columnAt(columnIndex) 访问表中的列。这将返回一个 Column 对象,您可以使用获取器 Column.theme 来设置该列所有单元格的属性。

table.columnAt(0).theme
  .setTextAlign(TextAlign.center);

通过上述代码可以看到,第一列的所有单元格都已居中对齐。

现在让我们看看如何更改特定行或列中特定单元格的属性。

可以通过 Dart 索引运算符访问行中的特定单元格,使用 Table[rowIndex][colIndex],或者从列中访问特定单元格,使用 Table.columnAt(colIndex)[cellIndex]

我们想更改索引行为 4 和列 2 中单元格 Founder Facebook 的属性。因此只需使用 table[4][2] 将字体颜色更改为 灰色,字体背景为 红色,字体样式为 划线

注意 要通过列访问此单元格,我们使用 table.columnAt(2)[4]

table[4][2].theme
  .setFontColor(Color.grey)
  .setFontBackground(Color.red)
  .setFontStyle({FontStyle.crossed});

tabulate 使用 Dart StringBuffer 类来渲染表格。有两种渲染表格的方法:一种是 StringBuffer,另一种是直接使用 Dart 内置的 print 函数打印 Table 对象。

使用 StringBuffer 打印:

StringBuffer stringBuffer = StringBuffer();
table.render(stringBuffer);
print(stringBuffer);

注意 1 tabulate 使用 TermColor 类进行样式化和着色。在这个类中有一个属性叫做 isAnsiColorDisabled,此属性全局启用或禁用 ANSI 转义序列。当环境不支持 ANSI 转义时,默认情况下设置为 true,并且 ANSI 转义不会添加到表中!但是可以通过覆盖来强制将 ANSI 转义添加到表中。

注意 2 某些 IDE 默认情况下设置为 true,但它们支持 ANSI 转义,因此您必须手动将 TermColor.isAnsiColorDisabled 设置为 false

最终结果将是:

样式选项

样式继承模型

tabulate 遵循简单的样式继承模型。在渲染每个单元格时:

  1. 如果指定了单元格样式,则应用单元格样式。
  2. 如果没有指定单元格样式,则应用其父行样式。
  3. 如果没有指定行样式,则应用其父表样式。
  4. 如果没有指定表样式,则应用默认表样式。

这使得即使指定了行或表样式,也可以覆盖特定单元格的样式,例如当整个行被涂成 黄色,但你希望某个特定单元格为 红色

注意 目前我们不支持嵌套表的样式继承。例如,当我们通过使用 Table.addRow 方法向另一个 Table 添加 Table 对象时,目标表不会应用其父表样式。

单词换行

tabulate 支持自动单词换行。

虽然单词换行是自动的,但有一个简单的覆盖。只有当单元格内容不包含任何内嵌的换行符 \n 时才会使用自动单词换行。因此,您可以在单元格内容中插入换行符 \n 并手动强制单词换行。

import 'package:tabulate/tabulate.dart';

void main() {
  Table table = Table();

  table.addRow([
    "This paragraph contains a veryveryveryveryveryverylong word. The long word will "
        "break and word wrap to the next line.",
    "This paragraph \nhas embedded '\\n' \ncharacters and\n will break\n exactly "
        "where\n you want it\n to\n break."
  ]);

  table[0][0].theme.setWidth(20);
  table[0][1].theme.setWidth(20);

  print(table);
}
  • 上面的表格有一行和两列。
  • 第一列的单元格具有自动单词换行。
  • 第二列的单元格使用单元格内容中的内嵌换行符 \n - 即使第二列有足够的空间(50个字符宽度),它也使用用户提供的换行符来分段并强制单元格样式。
  • 注意:无论单词换行是否自动,tabulate 都会对每个单元格的每一行执行修剪操作,以从行的两侧移除空白字符。

注意 目前单词换行与字体样式和颜色有一些问题,因为包装 ANSI 未实现到包装算法中。

文本对齐

tabulate 支持文本对齐。支持的对齐方式包括 左对齐右对齐居中对齐。通过方法 .theme.setTextAlign(alignment) 可以更改单元格的对齐方式。

注意 默认文本对齐方式为 左对齐

import 'package:tabulate/tabulate.dart';

void main() {
  TermColor.isAnsiColorDisabled = false;
  Table productTable = Table();

  productTable.addRow(["#", "Product Name", "Qty", "Price"]);

  productTable.addRow(["1", "TV", "4", "45,000"]);
  productTable.addRow(["2", "Mobile", "35", "32,000"]);
  productTable.addRow(["3", "Laptop", "12", "90,000"]);
  productTable.addRow(["4", "Keyboard", "3", "3,300"]);
  productTable.addRow(["5", "Shing Mach", "1", "18,500"]);

  productTable.columnAt(0).theme.setTextAlign(TextAlign.center);
  productTable.columnAt(3).theme.setWidth(15).setTextAlign(TextAlign.right);
  productTable.columnAt(2).theme.setWidth(8).setTextAlign(TextAlign.center);

  print(productTable);
}

上面的代码将 # 列和 Qty 列对齐到 居中,并将 Price 列对齐到 右对齐

字体样式

tabulate 支持许多字体样式,如 粗体暗淡斜体下划线闪烁反显隐藏划线

要设置字体样式,应使用方法 .theme.setFontStyle(fontstyles)。此方法的输入类型为 Set<FontStyle>,因为您可能需要应用一些字体样式的组合,例如 粗体和斜体

注意:根据环境,上述某些字体样式可能无法完美工作。

在对单元格应用字体样式时,我们也使用字体样式继承模型,并将父级的字体样式与单元格字体样式合并。例如,您全局设置了表的字体样式为 粗体,并在特定单元格上应用了 划线 字体样式,那么这些单元格将具有 粗体和划线 的样式。

import 'package:tabulate/tabulate.dart';

void main() {
  TermColor.isAnsiColorDisabled = false;

  Table styledTable = Table();
  styledTable.addRow(["Bold", "Italic", "Bold & Italic", "Blinking"]);
  styledTable.addRow(["Underline", "Crossed", "Dark", "Bold, Italic & Underlined"]);

  styledTable[0][0].theme.setFontStyle({FontStyle.bold});

  styledTable[0][1].theme.setFontStyle({FontStyle.italic});

  styledTable[0][2].theme.setFontStyle({FontStyle.bold, FontStyle.italic});

  styledTable[0][3].theme.setFontStyle({FontStyle.blink});

  styledTable[1][0].theme.setFontStyle({FontStyle.underline});

  styledTable[1][1].theme.setFontStyle({FontStyle.crossed});

  styledTable[1][2].theme.setFontStyle({FontStyle.dark});

  styledTable[1][3].theme.setFontStyle({FontStyle.bold, FontStyle.italic, FontStyle.underline});

  print(styledTable);
}

单元格颜色

TableTheme 对象有许多方法可以为字体、边框、角落和列分隔符着色 - 前景和背景。多亏了 termcolortabulate 支持 16 种颜色:灰色红色绿色黄色蓝色品红色青色白色亮红色亮绿色亮青色亮品红色亮蓝色亮黄色亮灰色亮白色。这些颜色的外观取决于您的终端。

对于字体、边框和角落,您可以调用 .theme.set<element>Color(value) 设置前景颜色,调用 .theme.set<element>Background(value) 设置背景颜色。以下是一个示例:

import 'package:tabulate/tabulate.dart';

void main() {
  TermColor.isAnsiColorDisabled = false;

  List<MapEntry<String, Color>> colors = [
    MapEntry("Grey", Color.grey),
    MapEntry("Red", Color.red),
    MapEntry("Green", Color.green),
    MapEntry("Yellow", Color.yellow),
    MapEntry("Blue", Color.blue),
    MapEntry("Magenta", Color.magenta),
    MapEntry("Cyan", Color.cyan),
    MapEntry("White", Color.white),
  ];
  List<MapEntry<String, Color>> brightColors = [
    MapEntry("Bright Grey", Color.brightGrey),
    MapEntry("Bright Red", Color.brightRed),
    MapEntry("Bright Green", Color.brightGreen),
    MapEntry("Bright Yellow", Color.brightYellow),
    MapEntry("Bright Blue", Color.brightBlue),
    MapEntry("Bright Magenta", Color.brightMagenta),
    MapEntry("Bright Cyan", Color.brightCyan),
    MapEntry("Bright White", Color.brightWhite),
  ];

  Table colorPalette = Table();

  colorPalette.addRow(colors.map((e) => e.key).toList());
  colorPalette.addRow(List.filled(colors.length, " "));
  colorPalette.addRow(brightColors.map((e) => e.key).toList());
  colorPalette.addRow(List.filled(brightColors.length, " "));

  colorPalette.theme
      .setBackground(Color.brightWhite)
      .setTextAlign(TextAlign.center)
      .setCorner("-")
      .setColor(Color.blue)
      .setWidth(9);

  colorPalette.rowAt(0).theme.setFontColor(Color.grey);
  colorPalette.rowAt(2).theme.setFontColor(Color.grey);

  for (int colorIndex = 0; colorIndex < 8; colorIndex++) {
    colorPalette[1][colorIndex].theme.setFontBackground(colors[colorIndex].value).setHeight(3);
    colorPalette[3][colorIndex].theme.setFontBackground(brightColors[colorIndex].value).setHeight(3);
  }

  Table colorsTable = Table();
  colorsTable.theme
      .setTextAlign(TextAlign.center)
      .setFontStyle({FontStyle.bold})
      .setColor(Color.brightWhite)
      .setFontBackground(Color.magenta);

  colorsTable.addRow(["Color Palette"]);
  colorsTable.addRow([colorPalette]);
  colorsTable.addRow(["Dart tabulate made with ❤ by Mhwmd."]);
  colorsTable.rowAt(2).theme.setFontBackground(Color.grey).setTextAlign(TextAlign.right).hideBorderBottom();

  print("$colorsTable");
}

更多关于Flutter表格生成插件dart_tabulate的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter表格生成插件dart_tabulate的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用dart_tabulate插件来生成表格的一个示例代码案例。请注意,dart_tabulate并非一个广为人知的Flutter插件,如果它确实存在,以下代码将基于一般表格生成插件的使用方式来模拟。如果dart_tabulate插件的具体API有所不同,请查阅其官方文档进行调整。

首先,确保你的pubspec.yaml文件中已经添加了dart_tabulate(或类似的表格生成插件)的依赖:

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

然后,运行flutter pub get来安装依赖。

接下来,在你的Flutter项目中创建一个简单的表格。以下是一个示例代码,展示如何使用一个假设的dart_tabulate插件来生成表格:

import 'package:flutter/material.dart';
import 'package:dart_tabulate/dart_tabulate.dart';  // 假设的包导入路径

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Table Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Table Example'),
        ),
        body: Center(
          child: TableWidget(),
        ),
      ),
    );
  }
}

class TableWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // 假设的表格数据
    List<List<String>> data = [
      ['Name', 'Age', 'City'],
      ['Alice', '30', 'New York'],
      ['Bob', '25', 'Los Angeles'],
      ['Charlie', '35', 'Chicago'],
    ];

    // 使用dart_tabulate生成表格(假设的API使用)
    // 注意:这里的API调用是基于假设的,实际使用时请参考dart_tabulate的文档
    return Container(
      padding: EdgeInsets.all(16.0),
      child: Tabulate(
        columns: data[0].length,  // 列数
        rows: data.length - 1,    // 行数(不包括表头)
        header: data[0],          // 表头
        data: data.sublist(1),    // 表格数据(不包括表头)
        cellBuilder: (context, value, rowIndex, columnIndex) {
          // 自定义单元格样式和内容
          return Center(
            child: Text(
              value,
              style: TextStyle(fontSize: 16),
            ),
          );
        },
        headerBuilder: (context, value, columnIndex) {
          // 自定义表头样式和内容
          return Container(
            decoration: BoxDecoration(
              color: Colors.blueGrey[100],
            ),
            padding: EdgeInsets.symmetric(horizontal: 8.0),
            child: Text(
              value,
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
          );
        },
      ),
    );
  }
}

// 假设的Tabulate组件(实际使用时由dart_tabulate插件提供)
class Tabulate extends StatelessWidget {
  final int columns;
  final int rows;
  final List<String> header;
  final List<List<String>> data;
  final Widget Function(BuildContext, String, int, int) cellBuilder;
  final Widget Function(BuildContext, String, int) headerBuilder;

  Tabulate({
    required this.columns,
    required this.rows,
    required this.header,
    required this.data,
    required this.cellBuilder,
    required this.headerBuilder,
  });

  @override
  Widget build(BuildContext context) {
    return Table(
      columnWidths: List.filled(columns, FlexColumnWidth(1)),
      border: TableBorder.all(color: Colors.black),
      children: [
        // 表头行
        TableRow(children: header.map((headerValue, index) {
          return headerBuilder(context, headerValue, index);
        }).toList()),
        // 数据行
        ...List.generate(rows, (rowIndex) {
          return TableRow(children: data[rowIndex].map((cellValue, columnIndex) {
            return cellBuilder(context, cellValue, rowIndex, columnIndex);
          }).toList());
        }),
      ],
    );
  }
}

请注意,上面的Tabulate类是一个假设的实现,用于展示如何自定义表格的生成。在实际使用中,dart_tabulate插件可能已经提供了类似的API,你只需按照其文档进行调用即可。如果dart_tabulate不存在或API不同,请查找其他类似的Flutter表格生成插件,如flutter_tabledata_table2,并根据其文档进行实现。

回到顶部