Table

Click Extra provides a way to render tables in the terminal.

Here how to use the standalone table rendering option decorator:

import click
from click_extra import pass_context, table_format_option, style, Color

@click.command
@table_format_option
@pass_context
def table_command(ctx):
    headers = ("Day", "Temperature")
    data = (
        (1, 42.9),
        ("2", None),
        (style("Friday", fg=Color.blue), style("Hot 🥵", fg=Color.red, bold=True)),
    )
    ctx.print_table(data, headers)

As you can see above, this option registers a ready-to-use print_table() method to the context object.

The default help message for this option list all available table formats:

$ table --help
Usage: table [OPTIONS]

Options:
  --table-format [asciidoc|csv|csv-excel|csv-excel-tab|csv-unix|double-grid|double-outline|fancy-grid|fancy-outline|github|grid|heavy-grid|heavy-outline|html|jira|latex|latex-booktabs|latex-longtable|latex-raw|mediawiki|mixed-grid|mixed-outline|moinmoin|orgtbl|outline|pipe|plain|presto|pretty|psql|rounded-grid|rounded-outline|rst|simple|simple-grid|simple-outline|textile|tsv|unsafehtml|vertical|youtrack]
                                  Rendering style of tables.
  --help                          Show this message and exit.

So you can use the --table-format option to change the table format:

$ table --table-format fancy-outline
╒════════╤═════════════╕
│ Day    │ Temperature │
╞════════╪═════════════╡
│ 1      │ 42.9        │
│ 2      │             │
│ FridayHot 🥵      │
╘════════╧═════════════╛
$ table --table-format asciidoc
[cols="8<,13<",options="header"]
|====
| Day    | Temperature 
| 1      | 42.9        
| 2      |             
| Friday | Hot 🥵      
|====

Tip

This example has been selected so you can see how print_table() handles:

  • Mixed data types (integers, floats, None, strings)

  • ANSI color codes (added with the click_extra.style() function)

  • Unicode characters (like the emojis)

Hint

There’s another method called render_table() that is registered in the context alongside print_table().

It works the same way, but instead of printing the table to the console, it returns the rendered table as a string.

Table formats

Table formats are aggregated from 3 sources:

They’re divided in 2 categories:

  • Formats that produce plain text output (like ASCII tables, grid tables, etc.) and are often composed of Unicode box-drawing characters, to be displayed in a terminal.

  • Formats that produce markup language output (like HTML, Markdown, LaTeX, etc.) and are expected to be rendered by a supporting viewer. This category also includes CSV and TSV formats, which are plain text but meant to be processed by other tools.

Format ID

Description

Implementation

Markup

asciidoc

AsciiDoc table

python-tabulate

csv

Comma-separated values

csv

csv-excel

CSV with Excel dialect

csv

csv-excel-tab

CSV with Excel tab dialect

csv

csv-unix

CSV with Unix dialect

csv

double-grid

Double-line grid table

python-tabulate

double-outline

Double-line outline table

python-tabulate

fancy-grid

Grid with Unicode box-drawing characters

python-tabulate

fancy-outline

Outline with Unicode box-drawing characters

python-tabulate

github

GitHub-flavored Markdown table

python-tabulate

grid

Grid table with ASCII characters, also supported by Pandoc and reStructuredText

python-tabulate

heavy-grid

Heavy-line grid table

python-tabulate

heavy-outline

Heavy-line outline table

python-tabulate

html

HTML table

python-tabulate

jira

Jira-style markup

python-tabulate

latex

LaTeX table

python-tabulate

latex-booktabs

LaTeX table with booktabs package

python-tabulate

latex-longtable

LaTeX longtable environment

python-tabulate

latex-raw

LaTeX table without escaping

python-tabulate

mediawiki

MediaWiki markup

python-tabulate

mixed-grid

Mixed-line grid table

python-tabulate

mixed-outline

Mixed-line outline table

python-tabulate

moinmoin

MoinMoin wiki markup

python-tabulate

orgtbl

Emacs org-mode table

python-tabulate

outline

Simple outline table

python-tabulate

pipe

PHP Markdown Extra pipes, also supported by Pandoc

python-tabulate

plain

Plain text, no formatting

python-tabulate

presto

Presto SQL output style

python-tabulate

pretty

Pretty ASCII table

python-tabulate

psql

PostgreSQL output style

python-tabulate

rounded-grid

Rounded grid table

python-tabulate

rounded-outline

Rounded outline table

python-tabulate

rst

reStructuredText simple table

python-tabulate

simple

Simple table with spaces, also supported by Pandoc

python-tabulate

simple-grid

Simple grid table

python-tabulate

simple-outline

Simple outline table

python-tabulate

textile

Textile markup

python-tabulate

tsv

Tab-separated values

python-tabulate

unsafehtml

HTML table without escaping

python-tabulate

vertical

Vertical table layout

cli-helpers

youtrack

YouTrack markup

python-tabulate

Todo

Explain extra parameters supported by print_table() for each category of formats.

$ table --table-format asciidoc
[cols="8<,13<",options="header"]
|====
| Day    | Temperature 
| 1      | 42.9        
| 2      |             
| Friday | Hot 🥵      
|====
$ table --table-format csv
Day,Temperature
1,42.9
2,
Friday,Hot 🥵
$ table --table-format csv-excel
Day,Temperature
1,42.9
2,
Friday,Hot 🥵
$ table --table-format csv-excel-tab
Day	Temperature
1	42.9
2	
Friday	Hot 🥵
$ table --table-format csv-unix
"Day","Temperature"
"1","42.9"
"2",""
"Friday","Hot 🥵"
$ table --table-format double-grid
╔════════╦═════════════╗
║ Day    ║ Temperature ║
╠════════╬═════════════╣
║ 1      ║ 42.9        ║
╠════════╬═════════════╣
║ 2      ║             ║
╠════════╬═════════════╣
║ FridayHot 🥵      ║
╚════════╩═════════════╝
$ table --table-format double-outline
╔════════╦═════════════╗
║ Day    ║ Temperature ║
╠════════╬═════════════╣
║ 1      ║ 42.9        ║
║ 2      ║             ║
║ FridayHot 🥵      ║
╚════════╩═════════════╝
$ table --table-format fancy-grid
╒════════╤═════════════╕
│ Day    │ Temperature │
╞════════╪═════════════╡
│ 1      │ 42.9        │
├────────┼─────────────┤
│ 2      │             │
├────────┼─────────────┤
│ FridayHot 🥵      │
╘════════╧═════════════╛
$ table --table-format fancy-outline
╒════════╤═════════════╕
│ Day    │ Temperature │
╞════════╪═════════════╡
│ 1      │ 42.9        │
│ 2      │             │
│ FridayHot 🥵      │
╘════════╧═════════════╛
$ table --table-format github
| Day    | Temperature |
| ------ | ----------- |
| 1      | 42.9        |
| 2      |             |
| Friday | Hot 🥵      |
$ table --table-format grid
+--------+-------------+
| Day    | Temperature |
+========+=============+
| 1      | 42.9        |
+--------+-------------+
| 2      |             |
+--------+-------------+
| Friday | Hot 🥵      |
+--------+-------------+
$ table --table-format heavy-grid
┏━━━━━━━━┳━━━━━━━━━━━━━┓
┃ Day    ┃ Temperature ┃
┣━━━━━━━━╋━━━━━━━━━━━━━┫
┃ 1      ┃ 42.9        ┃
┣━━━━━━━━╋━━━━━━━━━━━━━┫
┃ 2      ┃             ┃
┣━━━━━━━━╋━━━━━━━━━━━━━┫
┃ FridayHot 🥵      ┃
┗━━━━━━━━┻━━━━━━━━━━━━━┛
$ table --table-format heavy-outline
┏━━━━━━━━┳━━━━━━━━━━━━━┓
┃ Day    ┃ Temperature ┃
┣━━━━━━━━╋━━━━━━━━━━━━━┫
┃ 1      ┃ 42.9        ┃
┃ 2      ┃             ┃
┃ FridayHot 🥵      ┃
┗━━━━━━━━┻━━━━━━━━━━━━━┛
$ table --table-format html
<table>
<thead>
<tr><th>Day   </th><th>Temperature</th></tr>
</thead>
<tbody>
<tr><td>1     </td><td>42.9       </td></tr>
<tr><td>2     </td><td>           </td></tr>
<tr><td>Friday</td><td>Hot 🥵     </td></tr>
</tbody>
</table>
$ table --table-format jira
|| Day    || Temperature ||
| 1      | 42.9        |
| 2      |             |
| Friday | Hot 🥵      |
$ table --table-format latex
\begin{tabular}{ll}
\hline
 Day    & Temperature \\
\hline
 1      & 42.9        \\
 2      &             \\
 Friday & Hot 🥵      \\
\hline
\end{tabular}
$ table --table-format latex-booktabs
\begin{tabular}{ll}
\toprule
 Day    & Temperature \\
\midrule
 1      & 42.9        \\
 2      &             \\
 Friday & Hot 🥵      \\
\bottomrule
\end{tabular}
$ table --table-format latex-longtable
\begin{longtable}{ll}
\hline
 Day    & Temperature \\
\hline
\endhead
 1      & 42.9        \\
 2      &             \\
 Friday & Hot 🥵      \\
\hline
\end{longtable}
$ table --table-format latex-raw
\begin{tabular}{ll}
\hline
 Day    & Temperature \\
\hline
 1      & 42.9        \\
 2      &             \\
 Friday & Hot 🥵      \\
\hline
\end{tabular}
$ table --table-format mediawiki
{| class="wikitable" style="text-align: left;"
|+ <!-- caption -->
|-
! Day    !! Temperature
|-
| 1      || 42.9
|-
| 2      ||
|-
| Friday || Hot 🥵
|}
$ table --table-format mixed-grid
┍━━━━━━━━┯━━━━━━━━━━━━━┑
│ Day    │ Temperature │
┝━━━━━━━━┿━━━━━━━━━━━━━┥
│ 1      │ 42.9        │
├────────┼─────────────┤
│ 2      │             │
├────────┼─────────────┤
│ FridayHot 🥵      │
┕━━━━━━━━┷━━━━━━━━━━━━━┙
$ table --table-format mixed-outline
┍━━━━━━━━┯━━━━━━━━━━━━━┑
│ Day    │ Temperature │
┝━━━━━━━━┿━━━━━━━━━━━━━┥
│ 1      │ 42.9        │
│ 2      │             │
│ FridayHot 🥵      │
┕━━━━━━━━┷━━━━━━━━━━━━━┙
$ table --table-format moinmoin
|| ''' Day    ''' || ''' Temperature ''' ||
||  1       ||  42.9         ||
||  2       ||               ||
||  Friday  ||  Hot 🥵       ||
$ table --table-format orgtbl
| Day    | Temperature |
|--------+-------------|
| 1      | 42.9        |
| 2      |             |
| Friday | Hot 🥵      |
$ table --table-format outline
+--------+-------------+
| Day    | Temperature |
+========+=============+
| 1      | 42.9        |
| 2      |             |
| Friday | Hot 🥵      |
+--------+-------------+
$ table --table-format pipe
| Day    | Temperature |
|:-------|:------------|
| 1      | 42.9        |
| 2      |             |
| Friday | Hot 🥵      |
$ table --table-format plain
Day     Temperature
1       42.9
2
Friday  Hot 🥵
$ table --table-format presto
 Day    | Temperature
--------+-------------
 1      | 42.9
 2      |
 Friday | Hot 🥵
$ table --table-format pretty
+--------+-------------+
|  Day   | Temperature |
+--------+-------------+
|   1    |    42.9     |
|   2    |             |
| Friday |   Hot 🥵    |
+--------+-------------+
$ table --table-format psql
+--------+-------------+
| Day    | Temperature |
|--------+-------------|
| 1      | 42.9        |
| 2      |             |
| Friday | Hot 🥵      |
+--------+-------------+
$ table --table-format rounded-grid
╭────────┬─────────────╮
│ Day    │ Temperature │
├────────┼─────────────┤
│ 1      │ 42.9        │
├────────┼─────────────┤
│ 2      │             │
├────────┼─────────────┤
│ FridayHot 🥵      │
╰────────┴─────────────╯
$ table --table-format rounded-outline
╭────────┬─────────────╮
│ Day    │ Temperature │
├────────┼─────────────┤
│ 1      │ 42.9        │
│ 2      │             │
│ FridayHot 🥵      │
╰────────┴─────────────╯
$ table --table-format rst
======  ===========
Day     Temperature
======  ===========
1       42.9
2
Friday  Hot 🥵
======  ===========
$ table --table-format simple
Day     Temperature
------  -----------
1       42.9
2
Friday  Hot 🥵
$ table --table-format simple-grid
┌────────┬─────────────┐
│ Day    │ Temperature │
├────────┼─────────────┤
│ 1      │ 42.9        │
├────────┼─────────────┤
│ 2      │             │
├────────┼─────────────┤
│ FridayHot 🥵      │
└────────┴─────────────┘
$ table --table-format simple-outline
┌────────┬─────────────┐
│ Day    │ Temperature │
├────────┼─────────────┤
│ 1      │ 42.9        │
│ 2      │             │
│ FridayHot 🥵      │
└────────┴─────────────┘
$ table --table-format textile
|_.  Day    |_. Temperature |
|<. 1       |<. 42.9        |
|<. 2       |<.             |
|<. Friday  |<. Hot 🥵      |
$ table --table-format tsv
Day   	Temperature
1     	42.9
2
Friday	Hot 🥵
$ table --table-format unsafehtml
<table>
<thead>
<tr><th>Day   </th><th>Temperature</th></tr>
</thead>
<tbody>
<tr><td>1     </td><td>42.9       </td></tr>
<tr><td>2     </td><td>           </td></tr>
<tr><td>Friday</td><td>Hot 🥵     </td></tr>
</tbody>
</table>
$ table --table-format vertical
***************************[ 1. row ]***************************
Day         | 1
Temperature | 42.9
***************************[ 2. row ]***************************
Day         | 2
Temperature | 
***************************[ 3. row ]***************************
Day         | Friday
Temperature | Hot 🥵
$ table --table-format youtrack
||  Day     ||  Temperature  ||
|  1       |  42.9         |
|  2       |               |
|  Friday  |  Hot 🥵       |

Get table format

You can get the ID of the current table format from the context:

import click
from click_extra import echo, pass_context, table_format_option

@click.command
@table_format_option
@pass_context
def vanilla_command(ctx):
    format_id = ctx.meta["click_extra.table_format"]
    echo(f"Table format: {format_id}")

    data = ((1, 87), (2, 80), (3, 79))
    headers = ("day", "temperature")
    ctx.print_table(data, headers)
$ vanilla --table-format fancy-outline
Table format: fancy-outline
╒═════╤═════════════╕
│ day │ temperature │
╞═════╪═════════════╡
│ 1   │ 87          │
│ 2   │ 80          │
│ 3   │ 79          │
╘═════╧═════════════╛

click_extra.table API

        classDiagram
  Enum <|-- TableFormat
  ExtraOption <|-- TableFormatOption
    

Collection of table rendering utilities.

class click_extra.table.TableFormat(*values)[source]

Bases: Enum

Enumeration of supported table formats.

Hard-coded to be in alphabetical order. Content of this enum is checked in unit tests.

Warning

The youtrack format is missing in action from any official JetBrains documentation. So maybe it has been silently deprecated? Hence my proposal to remove it in python-tabulate#375.

ASCIIDOC = 'asciidoc'
CSV = 'csv'
CSV_EXCEL = 'csv-excel'
CSV_EXCEL_TAB = 'csv-excel-tab'
CSV_UNIX = 'csv-unix'
DOUBLE_GRID = 'double-grid'
DOUBLE_OUTLINE = 'double-outline'
FANCY_GRID = 'fancy-grid'
FANCY_OUTLINE = 'fancy-outline'
GITHUB = 'github'
GRID = 'grid'
HEAVY_GRID = 'heavy-grid'
HEAVY_OUTLINE = 'heavy-outline'
HTML = 'html'
JIRA = 'jira'
LATEX = 'latex'
LATEX_BOOKTABS = 'latex-booktabs'
LATEX_LONGTABLE = 'latex-longtable'
LATEX_RAW = 'latex-raw'
MEDIAWIKI = 'mediawiki'
MIXED_GRID = 'mixed-grid'
MIXED_OUTLINE = 'mixed-outline'
MOINMOIN = 'moinmoin'
ORGTBL = 'orgtbl'
OUTLINE = 'outline'
PIPE = 'pipe'
PLAIN = 'plain'
PRESTO = 'presto'
PRETTY = 'pretty'
PSQL = 'psql'
ROUNDED_GRID = 'rounded-grid'
ROUNDED_OUTLINE = 'rounded-outline'
RST = 'rst'
SIMPLE = 'simple'
SIMPLE_GRID = 'simple-grid'
SIMPLE_OUTLINE = 'simple-outline'
TEXTILE = 'textile'
TSV = 'tsv'
UNSAFEHTML = 'unsafehtml'
VERTICAL = 'vertical'
YOUTRACK = 'youtrack'
click_extra.table.MARKUP_FORMATS = {TableFormat.ASCIIDOC, TableFormat.CSV, TableFormat.CSV_EXCEL, TableFormat.CSV_EXCEL_TAB, TableFormat.CSV_UNIX, TableFormat.GITHUB, TableFormat.HTML, TableFormat.JIRA, TableFormat.LATEX, TableFormat.LATEX_BOOKTABS, TableFormat.LATEX_LONGTABLE, TableFormat.LATEX_RAW, TableFormat.MEDIAWIKI, TableFormat.MOINMOIN, TableFormat.ORGTBL, TableFormat.PIPE, TableFormat.RST, TableFormat.TEXTILE, TableFormat.TSV, TableFormat.UNSAFEHTML, TableFormat.YOUTRACK}

Subset of table formats that are considered as markup rendering.

click_extra.table.DEFAULT_FORMAT = TableFormat.ROUNDED_OUTLINE

Default table format, if none is specified.

click_extra.table.render_table(table_data, headers=None, table_format=None, **kwargs)[source]

Render a table and return it as a string.

Return type:

str

click_extra.table.print_table(table_data, headers=None, table_format=None, **kwargs)[source]

Render a table and print it to the console.

Return type:

None

class click_extra.table.TableFormatOption(param_decls=None, type=EnumChoice('asciidoc', 'csv', 'csv-excel', 'csv-excel-tab', 'csv-unix', 'double-grid', 'double-outline', 'fancy-grid', 'fancy-outline', 'github', 'grid', 'heavy-grid', 'heavy-outline', 'html', 'jira', 'latex', 'latex-booktabs', 'latex-longtable', 'latex-raw', 'mediawiki', 'mixed-grid', 'mixed-outline', 'moinmoin', 'orgtbl', 'outline', 'pipe', 'plain', 'presto', 'pretty', 'psql', 'rounded-grid', 'rounded-outline', 'rst', 'simple', 'simple-grid', 'simple-outline', 'textile', 'tsv', 'unsafehtml', 'vertical', 'youtrack'), default=TableFormat.ROUNDED_OUTLINE, expose_value=False, is_eager=True, help='Rendering style of tables.', **kwargs)[source]

Bases: ExtraOption

A pre-configured option that is adding a --table-format flag to select the rendering style of a table.

The selected table format ID is made available in the context in ctx.meta["click_extra.table_format"], and two helper methods are added to the context: - ctx.render_table(table_data, headers, **kwargs): renders and returns

the table as a string,

  • ctx.print_table(table_data, headers, **kwargs): renders and prints the table to the console.

Where: - table_data is a 2-dimensional iterable of iterables for rows and cells values, - headers is a list of string to be used as column headers, - **kwargs are any extra keyword arguments supported by the underlying table

formatting function.

init_formatter(ctx, param, table_format)[source]

Save in the context: table_format, render_table & print_table.

Return type:

None