The Table widget displays structured data in rows and columns with configurable borders, alignment, and styling.
When to Use
Use Table when you need to display structured, multi-column data. Common scenarios:
- Data display: Show records, configuration settings, or query results
- Comparison: Side-by-side feature comparisons or specifications
- Reports: Formatted output with headers, totals, and alignment
For simple key-value pairs, consider using a table with hidden headers or a Grid. For proportional data visualization, use BarChart or BreakdownChart.
Basic Usage
Add columns first, then rows. Each row must have the same number of cells as columns.
public static void BasicTableExample()
{
var table = new Table();
// Add columns
table.AddColumn("Name");
table.AddColumn("Age");
table.AddColumn("City");
// Add rows
table.AddRow("Alice", "28", "New York");
table.AddRow("Bob", "35", "London");
table.AddRow("Charlie", "42", "Tokyo");
AnsiConsole.Write(table);
}
Styling
Border Styles
Choose from 18 built-in border styles. Use RoundedBorder() for a modern look or AsciiBorder() for maximum compatibility.
public static void TableBordersExample()
{
ShowBorder("Square", t => t.SquareBorder());
ShowBorder("Rounded", t => t.RoundedBorder());
ShowBorder("Minimal", t => t.MinimalBorder());
ShowBorder("Heavy", t => t.HeavyBorder());
ShowBorder("Double", t => t.DoubleBorder());
ShowBorder("ASCII", t => t.AsciiBorder());
static void ShowBorder(string name, Func<Table, Table> setBorder)
{
var table = new Table();
setBorder(table);
table.AddColumn("Border");
table.AddColumn("Style");
table.AddRow(name, "Example");
AnsiConsole.Write(table);
AnsiConsole.WriteLine();
}
}
Note
Border Colors
Use BorderColor() to match your application's theme. Combine with markup in headers for emphasis.
public static void TableColorsExample()
{
var table = new Table()
.RoundedBorder()
.BorderColor(Color.Blue);
table.AddColumn("[yellow]Product[/]");
table.AddColumn("[yellow]Price[/]");
table.AddRow("Widget", "[green]$9.99[/]");
table.AddRow("Gadget", "[green]$19.99[/]");
AnsiConsole.Write(table);
}
Column Configuration
Alignment
Align column content with LeftAligned(), Centered(), or RightAligned(). Right-align numeric data for easier comparison.
public static void TableAlignmentExample()
{
var table = new Table();
table.AddColumn("Left", col => col.LeftAligned());
table.AddColumn("Center", col => col.Centered());
table.AddColumn("Right", col => col.RightAligned());
table.AddRow("Text", "Text", "Text");
table.AddRow("Aligned", "Aligned", "Aligned");
table.AddRow("Left", "Center", "Right");
AnsiConsole.Write(table);
}
Width and Padding
Fix column widths with Width(), adjust spacing with PadLeft() and PadRight(), or prevent wrapping with NoWrap().
public static void ColumnConfigurationExample()
{
var table = new Table();
// Fixed width column
table.AddColumn("ID", col => col.Width(5).Centered());
// Column with custom padding
table.AddColumn("Description", col => col.Width(30).PadLeft(2).PadRight(2));
// NoWrap column for long text
table.AddColumn("Status", col => col.NoWrap().RightAligned());
table.AddRow("001", "This is a longer description that will wrap within the column width", "Active");
table.AddRow("002", "Short text", "Pending");
AnsiConsole.Write(table);
}
Headers and Footers
Headers display by default. Add footers for totals or summaries. Use HideHeaders() for key-value style layouts.
public static void HeadersAndFootersExample()
{
var table = new Table();
// Add columns with footers
table.AddColumn("Item");
table.AddColumn("Quantity", col => col.RightAligned());
table.AddColumn("Price", col => col.RightAligned());
table.AddRow("Apples", "10", "$5.00");
table.AddRow("Oranges", "5", "$3.50");
table.AddRow("Bananas", "8", "$4.00");
// Add footers
table.Columns[0].Footer = new Text("Total", new Style(foreground: Color.Yellow));
table.Columns[1].Footer = new Text("23", new Style(foreground: Color.Yellow));
table.Columns[2].Footer = new Text("$12.50", new Style(foreground: Color.Green, decoration: Decoration.Bold));
AnsiConsole.Write(table);
}
Hidden Headers
Tables without headers work well for configuration or property displays.
public static void HiddenHeadersExample()
{
var table = new Table()
.HideHeaders()
.Border(TableBorder.None);
table.AddColumn("Key");
table.AddColumn("Value");
table.AddRow("[blue]Name:[/]", "Application");
table.AddRow("[blue]Version:[/]", "1.0.0");
table.AddRow("[blue]Status:[/]", "[green]Running[/]");
AnsiConsole.Write(table);
}
Titles and Captions
Add context with a title above the table and a caption below. Both support markup.
public static void TitlesAndCaptionsExample()
{
var table = new Table()
.RoundedBorder()
.BorderColor(Color.Aqua)
.Title("[yellow]Monthly Sales Report[/]")
.Caption("[grey]Data as of October 2025[/]");
table.AddColumn("Month");
table.AddColumn("Revenue", col => col.RightAligned());
table.AddRow("August", "$45,000");
table.AddRow("September", "$52,000");
table.AddRow("October", "$48,500");
AnsiConsole.Write(table);
}
Row Formatting
Row Separators
Use ShowRowSeparators() to add horizontal lines between rows, improving readability for dense data.
public static void RowSeparatorsExample()
{
var table = new Table()
.RoundedBorder()
.ShowRowSeparators();
table.AddColumn("Category");
table.AddColumn("Item");
table.AddColumn("Count", col => col.RightAligned());
table.AddRow("Fruits", "Apples", "10");
table.AddRow("Fruits", "Oranges", "5");
table.AddRow("Vegetables", "Carrots", "15");
table.AddRow("Vegetables", "Broccoli", "8");
AnsiConsole.Write(table);
}
Empty Rows
Insert empty rows to group related data visually.
public static void EmptyRowsExample()
{
var table = new Table()
.RoundedBorder();
table.AddColumn("Section");
table.AddColumn("Value");
table.AddRow("[yellow]Header Info[/]", "Data");
table.AddEmptyRow();
table.AddRow("[yellow]Body Info[/]", "Data");
table.AddEmptyRow();
table.AddRow("[yellow]Footer Info[/]", "Data");
AnsiConsole.Write(table);
}
Layout
By default, tables use minimum width. Use Expand() to fill available console width—useful for reports or dashboards.
public static void ExpandModeExample()
{
AnsiConsole.Write(new Markup("[yellow]Normal (collapsed) table:[/]\n"));
var normalTable = new Table();
normalTable.AddColumn("Name");
normalTable.AddColumn("Value");
normalTable.AddRow("Setting", "Value");
AnsiConsole.Write(normalTable);
AnsiConsole.WriteLine();
AnsiConsole.Write(new Markup("[yellow]Expanded table:[/]\n"));
var expandedTable = new Table()
.Expand();
expandedTable.AddColumn("Name");
expandedTable.AddColumn("Value");
expandedTable.AddRow("Setting", "Value");
AnsiConsole.Write(expandedTable);
}
Advanced Usage
Nested Tables
Embed tables within cells for hierarchical data or sub-groupings.
public static void NestedTablesExample()
{
// Create inner table
var innerTable = new Table()
.RoundedBorder()
.BorderColor(Color.Grey);
innerTable.AddColumn("Detail");
innerTable.AddColumn("Value");
innerTable.AddRow("CPU", "95%");
innerTable.AddRow("Memory", "12GB");
// Create outer table
var outerTable = new Table()
.SquareBorder();
outerTable.AddColumn("Server");
outerTable.AddColumn("Metrics");
outerTable.AddRow(new Text("server-01"), innerTable);
AnsiConsole.Write(outerTable);
}
Mixed Content
Cells accept any IRenderable—combine Markup, Panels, and other widgets for rich layouts.
public static void MixedContentExample()
{
var table = new Table()
.RoundedBorder();
table.AddColumn("Type");
table.AddColumn("Example");
// Markup in cells
table.AddRow(new Text("Markup"), new Markup("[bold green]Success[/] :check_mark:"));
// Panel in a cell
var panel = new Panel("[yellow]Warning[/]")
.BorderColor(Color.Yellow)
.Padding(1, 0);
table.AddRow(new Text("Panel"), panel);
// Styled text
table.AddRow(new Text("Text"), new Text("Styled Text", new Style(foreground: Color.Aqua, decoration: Decoration.Italic)));
AnsiConsole.Write(table);
}
Dynamic Updates
Modify tables at runtime with UpdateCell(), InsertRow(), and RemoveRow().
public static void DynamicTableExample()
{
var table = new Table()
.RoundedBorder();
table.AddColumn("ID");
table.AddColumn("Status");
table.AddColumn("Progress");
// Add initial rows
table.AddRow("Task 1", "[yellow]Pending[/]", "0%");
table.AddRow("Task 2", "[yellow]Pending[/]", "0%");
table.AddRow("Task 3", "[yellow]Pending[/]", "0%");
// Update cells dynamically
table.UpdateCell(0, 1, new Markup("[green]Complete[/]"));
table.UpdateCell(0, 2, new Markup("[green]100%[/]"));
table.UpdateCell(1, 1, new Markup("[blue]In Progress[/]"));
table.UpdateCell(1, 2, new Markup("[blue]45%[/]"));
// Insert a new row
table.InsertRow(3, new Markup("Task 4"), new Markup("[yellow]Pending[/]"), new Markup("0%"));
AnsiConsole.Write(table);
}
API Reference
A renderable table.
Constructors
Table()Initializes a new instance of the class.
Properties
Alignment
: Nullable<Justify>Border
: TableBorderBorderStyle
: StyleCaption
: TableTitleGets or sets the table footnote.
Columns
: IReadOnlyList<TableColumn>Gets the table columns.
Expand
: boolGets or sets a value indicating whether or not the table should fit the available space. If false, the table width will be auto calculated. Defaults to false.
Rows
: TableRowCollectionGets the table rows.
ShowFooters
: boolGets or sets a value indicating whether or not table footers should be shown.
ShowHeaders
: boolGets or sets a value indicating whether or not table headers should be shown.
ShowRowSeparators
: boolGets or sets a value indicating whether or not row separators should be shown.
Title
: TableTitleGets or sets the table title.
UseSafeBorder
: boolWidth
: Nullable<int>Gets or sets the width of the table.
Methods
Table AddColumn(TableColumn column)Adds a column to the table.
Parameters:
column (TableColumn)Returns:
The same instance so that multiple calls can be chained.
Extension Methods
Table AddColumn(string column, Action<TableColumn> configure)Adds a column to the table.
Parameters:
column (string)configure (Action<TableColumn>)Returns:
The same instance so that multiple calls can be chained.
Table AddColumns(TableColumn[] columns)Adds multiple columns to the table.
Parameters:
columns (TableColumn[])Returns:
The same instance so that multiple calls can be chained.
Table AddColumns(String[] columns)Adds multiple columns to the table.
Parameters:
columns (String[])Returns:
The same instance so that multiple calls can be chained.
Table AddEmptyRow()Adds an empty row to the table.
Returns:
The same instance so that multiple calls can be chained.
Table AddRow(IEnumerable<IRenderable> columns)Adds a row to the table.
Parameters:
columns (IEnumerable<IRenderable>)Returns:
The same instance so that multiple calls can be chained.
Table AddRow(IRenderable[] columns)Adds a row to the table.
Parameters:
columns (IRenderable[])Returns:
The same instance so that multiple calls can be chained.
Table AddRow(String[] columns)Adds a row to the table.
Parameters:
columns (String[])Returns:
The same instance so that multiple calls can be chained.
Table Caption(string text, Style style)Sets the table caption.
Parameters:
text (string)style (Style)Returns:
The same instance so that multiple calls can be chained.
Table Caption(TableTitle caption)Sets the table caption.
Parameters:
caption (TableTitle)Returns:
The same instance so that multiple calls can be chained.
IEnumerable<Segment> GetSegments(IAnsiConsole console)Gets the segments for a renderable using the specified console.
Parameters:
console (IAnsiConsole)Returns:
An enumerable containing segments representing the specified .
Table HideFooters()Hides table footers.
Returns:
The same instance so that multiple calls can be chained.
Table HideHeaders()Hides table headers.
Returns:
The same instance so that multiple calls can be chained.
Table HideRowSeparators()Hides row separators.
Returns:
The same instance so that multiple calls can be chained.
Table InsertRow(int index, IEnumerable<IRenderable> columns)Inserts a row in the table at the specified index.
Parameters:
index (int)columns (IEnumerable<IRenderable>)Returns:
The same instance so that multiple calls can be chained.
Table InsertRow(int index, IRenderable[] columns)Inserts a row in the table at the specified index.
Parameters:
index (int)columns (IRenderable[])Returns:
The same instance so that multiple calls can be chained.
Table InsertRow(int index, String[] columns)Inserts a row in the table at the specified index.
Parameters:
index (int)columns (String[])Returns:
The same instance so that multiple calls can be chained.
Table RemoveRow(int index)Removes a row from the table with the specified index.
Parameters:
index (int)Returns:
The same instance so that multiple calls can be chained.
Table ShowFooters()Shows table footers.
Returns:
The same instance so that multiple calls can be chained.
Table ShowHeaders()Shows table headers.
Returns:
The same instance so that multiple calls can be chained.
Table ShowRowSeparators()Shows row separators.
Returns:
The same instance so that multiple calls can be chained.
Table Title(string text, Style style)Sets the table title.
Parameters:
text (string)style (Style)Returns:
The same instance so that multiple calls can be chained.
Table Title(TableTitle title)Sets the table title.
Parameters:
title (TableTitle)Returns:
The same instance so that multiple calls can be chained.
Table UpdateCell(int rowIndex, int columnIndex, IRenderable cellData)Updates a tables cell.
Parameters:
rowIndex (int)columnIndex (int)cellData (IRenderable)Returns:
The same instance so that multiple calls can be chained.
Table UpdateCell(int rowIndex, int columnIndex, string cellData)Updates a tables cell.
Parameters:
rowIndex (int)columnIndex (int)cellData (string)Returns:
The same instance so that multiple calls can be chained.
Table Width(Nullable<int> width)Sets the table width.
Parameters:
width (Nullable<int>)Returns:
The same instance so that multiple calls can be chained.