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.

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

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.

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 : TableBorder
BorderStyle : Style
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
Width : Nullable<int>

Gets or sets the width of the table.

Methods

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(string column, Action<TableColumn> configure)

Adds a column to the table.

Parameters:

column (string)
The column to add.
configure (Action<TableColumn>)
Delegate that can be used to configure the added column.

Returns:

The same instance so that multiple calls can be chained.

Table AddColumns(TableColumn[] columns)

Adds multiple columns to the table.

Parameters:

columns (TableColumn[])
The columns to add.

Returns:

The same instance so that multiple calls can be chained.

Table AddColumns(String[] columns)

Adds multiple columns to the table.

Parameters:

columns (String[])
The columns to add.

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>)
The row columns to add.

Returns:

The same instance so that multiple calls can be chained.

Table AddRow(IRenderable[] columns)

Adds a row to the table.

Parameters:

columns (IRenderable[])
The row columns to add.

Returns:

The same instance so that multiple calls can be chained.

Table AddRow(String[] columns)

Adds a row to the table.

Parameters:

columns (String[])
The row columns to add.

Returns:

The same instance so that multiple calls can be chained.

Table Caption(string text, Style style)

Sets the table caption.

Parameters:

text (string)
The caption markup text.
style (Style)
The style.

Returns:

The same instance so that multiple calls can be chained.

Table Caption(TableTitle caption)

Sets the table caption.

Parameters:

caption (TableTitle)
The caption.

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)
The console.

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)
The index to insert the row at.
columns (IEnumerable<IRenderable>)
The row columns to add.

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)
The index to insert the row at.
columns (IRenderable[])
The row columns to add.

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)
The index to insert the row at.
columns (String[])
The row columns to add.

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)
The index to remove the row at.

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)
The table title markup text.
style (Style)
The table title style.

Returns:

The same instance so that multiple calls can be chained.

Table Title(TableTitle title)

Sets the table title.

Parameters:

title (TableTitle)
The table title.

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)
The index of row to update.
columnIndex (int)
The index of column to update.
cellData (IRenderable)
New cell data.

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)
The index of row to update.
columnIndex (int)
The index of column to update.
cellData (string)
New cell data.

Returns:

The same instance so that multiple calls can be chained.

Table Width(Nullable<int> width)

Sets the table width.

Parameters:

width (Nullable<int>)
The width.

Returns:

The same instance so that multiple calls can be chained.