Table Widget

Display tabular data with customizable columns, rows, borders, and styling

The Table widget displays structured data in rows and columns with configurable borders, alignment, and styling.

Screenshot

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.

csharp
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.

csharp
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

See the Table Border Reference for a visual guide to all border styles.

Border Colors

Use BorderColor() to match your application's theme. Combine with markup in headers for emphasis.

csharp
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.

csharp
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().

csharp
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.

csharp
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.

csharp
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.

csharp
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.

csharp
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.

csharp
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.

csharp
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.

csharp
// 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.

csharp
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().

csharp
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);

See Also

API Reference

A renderable table.

Constructors

public Table()

Initializes a new instance of the Table class.

Properties

Border : TableBorder

Gets or sets the border.

Caption : TableTitle

Gets or sets the table footnote.

Columns : IReadOnlyList<TableColumn>

Gets the table columns.

Expand : bool

Gets 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 : TableRowCollection

Gets the table rows.

ShowFooters : bool

Gets or sets a value indicating whether or not table footers should be shown.

ShowHeaders : bool

Gets or sets a value indicating whether or not table headers should be shown.

ShowRowSeparators : bool

Gets or sets a value indicating whether or not row separators should be shown.

Title : TableTitle

Gets or sets the table title.

UseSafeBorder : bool

Gets or sets a value indicating whether or not to use a "safe" border on legacy consoles that might not be able to render non-ASCII characters.

Width : int?

Gets or sets the width of the table.

Methods

public Table AddColumn(TableColumn column)

Adds a column to the table.

Parameters:

column (TableColumn)
The column to add.

Returns:

The same instance so that multiple calls can be chained.

Extension Methods

Table AddColumn(this Table table, string column, Action<TableColumn> configure)

Adds a column to the table.

Returns:

The same instance so that multiple calls can be chained.

Table AddColumns(this Table table, string[] columns)

Adds multiple columns to the table.

Returns:

The same instance so that multiple calls can be chained.

Table AddColumns(this Table table, TableColumn[] columns)

Adds multiple columns to the table.

Returns:

The same instance so that multiple calls can be chained.

Table AddEmptyRow(this Table table)

Adds an empty row to the table.

Returns:

The same instance so that multiple calls can be chained.

Table AddRow(this Table table, string[] columns)

Adds a row to the table.

Returns:

The same instance so that multiple calls can be chained.

Table AddRow(this Table table, IRenderable[] columns)

Adds a row to the table.

Returns:

The same instance so that multiple calls can be chained.

Table AddRow(this Table table, IEnumerable<IRenderable> columns)

Adds a row to the table.

Returns:

The same instance so that multiple calls can be chained.

Table HideFooters(this Table table)

Hides table footers.

Returns:

The same instance so that multiple calls can be chained.

Table HideHeaders(this Table table)

Hides table headers.

Returns:

The same instance so that multiple calls can be chained.

Table HideRowSeparators(this Table table)

Hides row separators.

Returns:

The same instance so that multiple calls can be chained.

Table InsertRow(this Table table, int index, string[] columns)

Inserts a row in the table at the specified index.

Returns:

The same instance so that multiple calls can be chained.

Table InsertRow(this Table table, int index, IRenderable[] columns)

Inserts a row in the table at the specified index.

Returns:

The same instance so that multiple calls can be chained.

Table InsertRow(this Table table, int index, IEnumerable<IRenderable> columns)

Inserts a row in the table at the specified index.

Returns:

The same instance so that multiple calls can be chained.

Table RemoveRow(this Table table, int index)

Removes a row from the table with the specified index.

Returns:

The same instance so that multiple calls can be chained.

Table ShowFooters(this Table table)

Shows table footers.

Returns:

The same instance so that multiple calls can be chained.

Table ShowHeaders(this Table table)

Shows table headers.

Returns:

The same instance so that multiple calls can be chained.

Table ShowRowSeparators(this Table table)

Shows row separators.

Returns:

The same instance so that multiple calls can be chained.

Table UpdateCell(this Table table, int rowIndex, int columnIndex, string cellData)

Updates a tables cell.

Returns:

The same instance so that multiple calls can be chained.

Table UpdateCell(this Table table, int rowIndex, int columnIndex, IRenderable cellData)

Updates a tables cell.

Returns:

The same instance so that multiple calls can be chained.

Table Width(this Table table, int? width)

Sets the table width.

Returns:

The same instance so that multiple calls can be chained.