Skip to main content

DataTable2

Enhanced data table for Flet that adds sticky headers, fixed rows/columns, and other UX improvements via the flet-datatable2 extension.

It wraps the Flutter data_table_2 package.

Platform Support

PlatformWindowsmacOSLinuxiOSAndroidWeb
Supported

Usage

Add flet-datatable2 to your project dependencies:

uv add flet-datatable2

Examples

Example 1

import flet as ft
import flet_datatable2 as fdt


def main(page: ft.Page):
page.add(
ft.SafeArea(
content=fdt.DataTable2(
empty=ft.Text("This table is empty."),
columns=[
fdt.DataColumn2(label=ft.Text("First name")),
fdt.DataColumn2(label=ft.Text("Last name")),
fdt.DataColumn2(label=ft.Text("Age"), numeric=True),
],
),
)
)


if __name__ == "__main__":
ft.run(main)

Example 2

from data import desserts

import flet as ft
import flet_datatable2 as ftd


def main(page: ft.Page):
page.vertical_alignment = ft.MainAxisAlignment.CENTER
page.horizontal_alignment = ft.CrossAxisAlignment.CENTER

sorted_desserts = list(desserts)
data_table: ftd.DataTable2 | None = None

def handle_row_selection_change(e: ft.Event[ftd.DataRow2]) -> None:
e.control.selected = not e.control.selected
e.control.update()

def sort_column(e: ft.DataColumnSortEvent) -> None:
if data_table is None:
return

sorters = [
lambda d: d.name.lower(),
lambda d: d.calories,
lambda d: d.fat,
lambda d: d.carbs,
lambda d: d.protein,
lambda d: d.sodium,
lambda d: d.calcium,
lambda d: d.iron,
]
sorted_desserts.sort(key=sorters[e.column_index], reverse=not e.ascending)
data_table.rows = get_data_rows(sorted_desserts)
data_table.sort_column_index = e.column_index
data_table.sort_ascending = e.ascending
data_table.update()

def get_data_columns() -> list[ftd.DataColumn2]:
return [
ftd.DataColumn2(
label=ft.Text("Name"),
size=ftd.DataColumnSize.L,
on_sort=sort_column,
heading_row_alignment=ft.MainAxisAlignment.START,
),
ftd.DataColumn2(
label=ft.Text("Calories"),
on_sort=sort_column,
numeric=True,
heading_row_alignment=ft.MainAxisAlignment.END,
),
ftd.DataColumn2(label=ft.Text("Fat"), on_sort=sort_column, numeric=True),
ftd.DataColumn2(label=ft.Text("Carbs"), on_sort=sort_column, numeric=True),
ftd.DataColumn2(
label=ft.Text("Protein"),
on_sort=sort_column,
numeric=True,
),
ftd.DataColumn2(label=ft.Text("Sodium"), on_sort=sort_column, numeric=True),
ftd.DataColumn2(
label=ft.Text("Calcium"),
on_sort=sort_column,
numeric=True,
),
ftd.DataColumn2(label=ft.Text("Iron"), on_sort=sort_column, numeric=True),
]

def get_data_rows(items: list) -> list[ftd.DataRow2]:
return [
ftd.DataRow2(
specific_row_height=50,
on_select_change=handle_row_selection_change,
cells=[
ft.DataCell(content=ft.Text(dessert.name)),
ft.DataCell(content=ft.Text(dessert.calories)),
ft.DataCell(content=ft.Text(dessert.fat)),
ft.DataCell(content=ft.Text(dessert.carbs)),
ft.DataCell(content=ft.Text(dessert.protein)),
ft.DataCell(content=ft.Text(dessert.sodium)),
ft.DataCell(content=ft.Text(dessert.calcium)),
ft.DataCell(content=ft.Text(dessert.iron)),
],
)
for dessert in items
]

data_table = ftd.DataTable2(
show_checkbox_column=True,
expand=True,
column_spacing=0,
heading_row_color=ft.Colors.SECONDARY_CONTAINER,
horizontal_margin=12,
sort_ascending=True,
bottom_margin=10,
min_width=600,
on_select_all=lambda _: print("All selected"),
columns=get_data_columns(),
rows=get_data_rows(sorted_desserts),
)

page.add(
ft.SafeArea(
content=data_table,
)
)


if __name__ == "__main__":
ft.run(main)

Description

Provides sticky header row, scrollable data rows, and additional layout flexibility with DataColumn2 and DataRow2.

Note

DataTable2 doesn't support flet.DataTable.data_row_min_height and flet.DataTable.data_row_max_height properties present in the parent DataTable. Use data_row_height instead.

Inherits: DataTable

Properties

Properties

bottom_marginclass-attributeinstance-attribute

bottom_margin: Optional[Number] = None

Adds space after the last row if set.

checkbox_alignmentclass-attributeinstance-attribute

checkbox_alignment: Alignment = field(default_factory=(lambda: Alignment.CENTER))

Alignment of the checkbox.

columnsinstance-attribute

columns: list[Union[DataColumn2, DataColumn]]

A list of table columns.

data_row_checkbox_themeclass-attributeinstance-attribute

data_row_checkbox_theme: Optional[CheckboxTheme] = None

Overrides theme of checkboxes in each data row.

data_row_heightclass-attributeinstance-attribute

data_row_height: Optional[Number] = None

Height of each data row.

data_row_max_heightclass-attributeinstance-attribute

data_row_max_height: None = field(init=False, repr=False, compare=False, metadata={'skip': True})

data_row_min_heightclass-attributeinstance-attribute

data_row_min_height: None = field(init=False, repr=False, compare=False, metadata={'skip': True})

emptyclass-attributeinstance-attribute

empty: Optional[Control] = None

Placeholder control shown when there are no data rows.

fixed_columns_colorclass-attributeinstance-attribute

fixed_columns_color: Optional[ColorValue] = None

Background color for sticky left columns.

fixed_corner_colorclass-attributeinstance-attribute

fixed_corner_color: Optional[ColorValue] = None

Background color of the fixed top-left corner cell.

fixed_left_columnsclass-attributeinstance-attribute

fixed_left_columns: int = 0

Number of sticky columns on the left. Includes checkbox column, if present.

fixed_top_rowsclass-attributeinstance-attribute

fixed_top_rows: int = 1

Number of sticky rows from the top. Includes heading row by default.

heading_checkbox_themeclass-attributeinstance-attribute

heading_checkbox_theme: Optional[CheckboxTheme] = None

Overrides theme of the heading checkbox.

lm_ratioclass-attributeinstance-attribute

lm_ratio: Number = 1.2

Ratio of Large column width to Medium.

min_widthclass-attributeinstance-attribute

min_width: Optional[Number] = None

Minimum table width before horizontal scrolling kicks in.

rowsclass-attributeinstance-attribute

rows: list[Union[DataRow, DataRow2]] = field(default_factory=list)

A list of table rows.

show_heading_checkboxclass-attributeinstance-attribute

show_heading_checkbox: bool = True

Controls visibility of the heading checkbox.

sm_ratioclass-attributeinstance-attribute

sm_ratio: Number = 0.67

Ratio of Small column width to Medium.

sort_arrow_animation_durationclass-attributeinstance-attribute

sort_arrow_animation_duration: DurationValue = field(default_factory=(lambda: Duration(milliseconds=150)))

Duration of sort arrow animation.

sort_arrow_iconclass-attributeinstance-attribute

sort_arrow_icon: IconData = Icons.ARROW_UPWARD

Icon shown when sorting is applied.

sort_arrow_icon_colorclass-attributeinstance-attribute

sort_arrow_icon_color: Optional[ColorValue] = None

When set always overrides/preceeds default arrow icon color.

visible_horizontal_scroll_barclass-attributeinstance-attribute

visible_horizontal_scroll_bar: Optional[bool] = None

Determines visibility of the horizontal scrollbar.

visible_vertical_scroll_barclass-attributeinstance-attribute

visible_vertical_scroll_bar: Optional[bool] = None

Determines visibility of the vertical scrollbar.