flutter_grouped_table 1.0.1
flutter_grouped_table: ^1.0.1 copied to clipboard
A Flutter package for creating tables with merged cells (cell merge) support, especially useful for grouped headers.
flutter_grouped_table #
A Flutter package for creating tables with merged cells (cell merge) support, especially useful for grouped headers.
Features #
- ✅ Cell Merge Support: Merge cells across multiple rows/columns in headers and data rows
- ✅ Grouped Headers: Automatic multi-row header layout with nested structures (e.g., "Sales" with "Q1", "Q2", "Q3", "Q4" sub-headers)
- ✅ Row Span: Explicit row span support in data cells
- ✅ Column Span: Column span support in both headers and data rows
- ✅ Simple API: Easy-to-use API for common use cases with simple data structures
- ✅ Advanced API: Full control with data models for complex scenarios
- ✅ Customizable: Customize cell styles, colors, borders, and more
- ✅ Responsive: Use flex weights to control column sizes
Installation #
Add this to your package's pubspec.yaml file:
dependencies:
flutter_grouped_table: ^1.0.1
Then run:
flutter pub get
Usage #
Simple API (Recommended for Most Cases) #
The simplest way to create a table is using GroupedTable.fromSimpleData():
import 'package:flutter_grouped_table/flutter_grouped_table.dart';
GroupedTable.fromSimpleData(
headerRows: [
[
'Product',
'Category',
{'text': 'Sales', 'children': ['Q1', 'Q2', 'Q3', 'Q4']}
]
],
dataRows: [
['Laptop', 'Electronics', '120', '150', '180', '200'],
['Smartphone', null, '250', '280', '300', '320'],
['Tablet', null, '80', '90', '100', '110'],
],
rowSpanMap: {
0: {1: 3}, // Row 0, Column 1 spans 3 rows
},
columnFlexWeights: [2, 1, 1, 1, 1, 1],
// Optional: control the overall table size
// tableWidth: 900,
// tableHeight: 500,
// tableConstraints: const BoxConstraints(minWidth: 900),
)
Key Points:
- Use
nullin data rows to indicate a cell is merged from the previous row - Use
rowSpanMapto specify which cells span multiple rows:{rowIndex: {colIndex: rowSpan}} - For grouped headers, use a Map:
{'text': 'Header', 'children': ['Sub1', 'Sub2']}
Row Span Example #
To create vertically merged cells, use rowSpanMap:
GroupedTable.fromSimpleData(
headerRows: [
['Product', 'Category', 'Q1', 'Q2', 'Q3', 'Q4']
],
dataRows: [
['Laptop', 'Electronics', '120', '150', '180', '200'],
['Smartphone', null, '250', '280', '300', '320'], // null = merged from row 0
['Tablet', null, '80', '90', '100', '110'], // null = merged from row 0
],
rowSpanMap: {
0: {1: 3}, // Row 0, Column 1 (Category) spans 3 rows
},
)
Per-row and Per-cell Heights #
You can control row heights per-row using the rowHeights parameter (passed to GroupedTable or fromSimpleData). A null entry falls back to the global rowHeight.
// Make some rows taller than the default 40.0
GroupedTable.fromSimpleData(
headerRows: [ /* ... */ ],
dataRows: [ /* ... */ ],
rowHeight: 40.0,
rowHeights: const [60.0, 40.0, 50.0, 40.0, 70.0],
);
If you need to override the height of a specific data cell, build the advanced API and set height on a GroupedTableDataCell.
final dataRows = [
[
GroupedTableDataCell.text('Laptop'),
GroupedTableDataCell(
child: const Text('Electronics'),
height: 80.0, // cell-specific override
rowSpan: 1,
),
// ...
],
// ...
];
GroupedTable(
headerRows: [ /* ... */ ],
dataRows: dataRows,
rowHeight: 40.0,
);
Notes:
GroupedTableDataCell.heighttakes precedence overrowHeightsandrowHeight.- Row-spanned cell heights are calculated as the sum of the effective heights of the spanned rows plus
rowSpacingbetween rows.
Advanced API (Full Control) #
For advanced use cases requiring custom widgets or fine-grained control:
final headerRow = [
GroupedTableCell.simple('Product'),
GroupedTableCell.simple('Category'),
GroupedTableCell.grouped(
text: 'Sales',
children: [
GroupedTableCell.simple('Q1'),
GroupedTableCell.simple('Q2'),
GroupedTableCell.simple('Q3'),
GroupedTableCell.simple('Q4'),
],
),
];
final dataRows = [
[
GroupedTableDataCell.text('Laptop'),
GroupedTableDataCell.rowSpan(
child: const Text('Electronics'),
rowSpan: 3,
),
GroupedTableDataCell.text('120'),
GroupedTableDataCell.text('150'),
GroupedTableDataCell.text('180'),
GroupedTableDataCell.text('200'),
],
[
GroupedTableDataCell.text('Smartphone'),
GroupedTableDataCell.text('250'),
GroupedTableDataCell.text('280'),
GroupedTableDataCell.text('300'),
GroupedTableDataCell.text('320'),
],
];
GroupedTable(
headerRows: [headerRow],
dataRows: dataRows,
columnFlexWeights: [2, 1, 1, 1, 1, 1],
)
API Reference #
GroupedTable.fromSimpleData #
Factory constructor for creating tables from simple data structures.
Parameters
headerRows(required): List of header rows. Each row can contain:String: Simple header textMap: Grouped header with{'text': 'Header', 'children': ['Sub1', 'Sub2']}
dataRows(required): List of data rows. Each cell can be:String: Text contentWidget: Custom widgetnull: Merged cell (skipped, part of rowSpan from previous row)TableCellData: Advanced cell configuration
rowSpanMap: Map specifying row spans:{rowIndex: {colIndex: rowSpan}}columnFlexWeights: Flex weights for columnsborderColor: Border color (default:Colors.black)borderWidth: Border width (default:1.0)borderRadius: Table border radiusheaderBackgroundColor: Background color for header cellsdataBackgroundColor: Background color for data cellsheaderTextStyle: Default text style for headersdataTextStyle: Default text style for data cellsdefaultHeaderHeight: Default header cell height (default:40.0)rowHeight: Default data row height (default:40.0)rowSpacing: Vertical spacing between rows (default:0)
GroupedTable #
Main table widget (advanced API).
Properties
headerRows(required): List of header row configurations (List<List<GroupedTableCell>>)dataRows(required): List of data rows (List<List<GroupedTableDataCell>>)columnFlexWeights: Flex weights for columnsborderColor: Border color (default:Colors.black)borderWidth: Border width (default:1.0)borderRadius: Table border radiusheaderBackgroundColor: Background color for header cellsdataBackgroundColor: Background color for data cellsheaderTextStyle: Default text style for headersdataTextStyle: Default text style for data cellsdefaultHeaderHeight: Default header cell height (default:40.0)rowHeight: Default data row height (default:40.0)rowSpacing: Vertical spacing between rows (default:0)
GroupedTableCell #
Represents a header cell in the table.
Constructors
GroupedTableCell(): Default constructorGroupedTableCell.simple(String text): Simple text cellGroupedTableCell.merged(): Merged cell spanning multiple columns/rowsGroupedTableCell.grouped(): Grouped header with nested children (automatically creates multi-row header)
GroupedTableDataCell #
Represents a data cell in the table.
Constructors
GroupedTableDataCell(): Default constructor withchildwidgetGroupedTableDataCell.text(String text): Simple text cellGroupedTableDataCell.merged(): Merged cell spanning multiple columns/rowsGroupedTableDataCell.rowSpan(): Cell with row span
TableCellData #
Helper class for advanced cell configuration in simple API.
Constructors
TableCellData.text(String text): Simple text cellTableCellData.rowSpan(dynamic value, int rowSpan): Cell with row spanTableCellData.empty(): Empty cell (for merged cells)
Example #
See the example/ folder for more examples.
cd example
flutter run
License #
MIT License
Copyright (c) 2026 JeHee Yu