Click Extra provides a way to render tables in the terminal.
Here how to use the standalone table rendering option decorator:
:emphasize-lines: 5,14
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:
:emphasize-lines: 5-6
result = invoke(table_command, args=["--help"])
assert "--table-format" in result.stdout
So you can use the --table-format option to change the table format:
from textwrap import dedent
result = invoke(table_command, args=["--table-format", "fancy-outline"])
assert result.stdout == dedent("""\
╒════════╤═════════════╕
│ Day │ Temperature │
╞════════╪═════════════╡
│ 1 │ 42.9 │
│ 2 │ │
│ \x1b[34mFriday\x1b[0m │ \x1b[31m\x1b[1mHot 🥵\x1b[0m │
╘════════╧═════════════╛
""")
from textwrap import dedent
result = invoke(table_command, args=["--table-format", "asciidoc"])
assert result.stdout == (
'[cols="<8,<13",options="header"]\n'
'|====\n'
'| Day | Temperature \n'
'| 1 | 42.9 \n'
'| 2 | \n'
'| Friday | Hot 🥵 \n'
'|====\n'
)
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)
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 are aggregated from these sources:
python-tabulatecli-helpers- Python's
csvmodule from the standard library - Python's
jsonmodule from the standard library hjson(requires the[hjson]extra)tomlkit(requires the[toml]extra)xmltodict(requires the[xml]extra)PyYAML(requires the[yaml]extra)
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, TSV, and structured serialization formats (HJSON, JSON, JSON5, JSONC, TOML, XML, YAML), which are plain text but meant to be processed by other tools.
| Format ID | Description | Implementation | Markup |
|---|---|---|---|
aligned |
Compact table with single-space column separators and no borders | Click Extra | ❌ |
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 |
❌ |
hjson |
HJSON array of objects | hjson |
✅ |
html |
HTML table | python-tabulate |
✅ |
jira |
Jira-style markup | python-tabulate |
✅ |
json |
JSON array of objects | json |
✅ |
json5 |
Alias for json (JSON5 is a superset of JSON) |
json |
✅ |
jsonc |
Alias for json (JSONC is JSON with comments) |
json |
✅ |
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 |
✅ |
toml |
TOML array of tables | tomlkit |
✅ |
tsv |
Tab-separated values | python-tabulate |
✅ |
unsafehtml |
HTML table without escaping | python-tabulate |
✅ |
vertical |
Vertical table layout | cli-helpers |
❌ |
xml |
XML document | xmltodict |
✅ |
yaml |
YAML sequence of mappings | PyYAML |
✅ |
youtrack |
YouTrack markup | python-tabulate |
✅ |
By default, markup formats strip ANSI color codes from the output, to avoid injecting escape sequences into structured content like HTML, LaTeX, or CSV.
If you want to keep them, force the `--color` option when invoking the command.
Use the built-in `click-extra render-matrix` command to verify how ANSI codes are handled by each format:
```shell-session
$ uvx click-extra --table-format github render-matrix --matrix=styles
$ uvx click-extra --table-format json render-matrix --matrix=colors
```
Plain-text formats preserve ANSI styling. Markup formats strip it unless `--color` is passed explicitly.
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "aligned"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "asciidoc"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "csv"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "csv-excel"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "csv-excel-tab"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "csv-unix"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "double-grid"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "double-outline"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "fancy-grid"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "fancy-outline"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "github"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "grid"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "heavy-grid"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "heavy-outline"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "hjson"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "html"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "jira"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "json"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "json5"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "jsonc"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "latex"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "latex-booktabs"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "latex-longtable"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "latex-raw"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "mediawiki"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "mixed-grid"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "mixed-outline"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "moinmoin"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "orgtbl"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "outline"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "pipe"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "plain"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "presto"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "pretty"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "psql"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "rounded-grid"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "rounded-outline"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "rst"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "simple"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "simple-grid"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "simple-outline"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "textile"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "toml"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "tsv"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "unsafehtml"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "vertical"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "xml"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "yaml"])
:emphasize-lines: 1
invoke(table_command, args=["--table-format", "youtrack"])
You can get the ID of the current table format from the context:
:emphasize-lines: 8-9
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)
:emphasize-lines: 2
result = invoke(vanilla_command, args=["--table-format", "fancy-outline"])
assert "Table format: fancy-outline" in result.stdout
:strict:
:members:
:undoc-members:
:show-inheritance: