tabulate has options headers and showindex
table = tb.tabulate(data, tablefmt='html', headers=df.columns, showindex=True)
st.markdown(table, unsafe_allow_html=True)

Source code: tabulate
You can also add CSS to change it
table = tb.tabulate(data, tablefmt='html', headers=df.columns, showindex=True)
st.write('<style>table th {font-size: 30px; color: red} table tr:nth-child(odd) td {background-color: #eee}</style>', unsafe_allow_html=True)
st.markdown(table, unsafe_allow_html=True)

But you may also use DataFrame to generate HTML without tabulate.
And it may use df.style with many functions to format every cell.
This example changes background for maximal and minimal value in columns A and B
df = pd.DataFrame(data)
def highlight_max(x, props):
return np.where(x == np.nanmax(x.to_numpy()), props, None)
def highlight_min(x, props):
return np.where(x == np.nanmin(x.to_numpy()), props, None)
df = df.style \
.apply(highlight_max, props='background-color: #fed', subset=['A','B'], axis=0) \
.apply(highlight_min, props='background-color: #afa', subset=['A','B'], axis=0)
html = df.to_html()
st.write(html, unsafe_allow_html=True)

Full code:
import tabulate as tb
import streamlit as st
import pandas as pd
import numpy as np
np.random.seed(42)
data = {
'A': np.random.rand(5),
'B': np.random.randint(1, 100, size=5),
'C': np.random.choice(['X', 'Y', 'Z'], size=5)
}
df = pd.DataFrame(data)
def highlight_max(x, props):
return np.where(x == np.nanmax(x.to_numpy()), props, None)
def highlight_min(x, props):
return np.where(x == np.nanmin(x.to_numpy()), props, None)
df = df.style \
.apply(highlight_max, props='background-color: #fed', subset=['A','B'], axis=0) \
.apply(highlight_min, props='background-color: #afa', subset=['A','B'], axis=0)
html = df.to_html()
st.write(html, unsafe_allow_html=True)
table = tb.tabulate(data, tablefmt='html', headers=df.columns, showindex=True)
st.write('<style>table th {font-size: 30px; color: red} table tr:nth-child(odd) td {background-color: #eee}</style>', unsafe_allow_html=True)
st.markdown(table, unsafe_allow_html=True)
Answer from furas on Stack OverflowPyPI
pypi.org › project › tabulate
tabulate · PyPI
Options: -h, --help show this message -1, --header use the first row of data as a table header -o FILE, --output FILE print table to FILE (default: stdout) -s REGEXP, --sep REGEXP use a custom column separator (default: whitespace) -F FPFMT, --float FPFMT floating point number format (default: g) -I INTFMT, --int INTFMT integer point number format (default: "") -f FMT, --format FMT set output table format; supported formats: plain, simple, github, grid, fancy_grid, pipe, orgtbl, rst, mediawiki, html, latex, latex_raw, latex_booktabs, latex_longtable, tsv (default: simple) Such features as decimal point alignment and trying to parse everything as a number imply that tabulate:
» pip install tabulate
HTML format with grid
The existing "html" tablefmt produces good html tables but the are missing a border: Maybe a good idea will be to add a "grid_html" tablefmt to produce the exact same table but ... More on github.com
Python - HTML - Send HTML Table with CSS Style - Stack Overflow
I'm trying to send a email with a table as a body with some CSS configurations. For that I have the following code: import csv from tabulate import tabulate from email.mime.multipart import More on stackoverflow.com
smtplib - Printing mutiple HTML tables using tabulate in python - Stack Overflow
I want to produce two HTML tables using tabulate package, but I am only able to produce one table and send mail. Is it possible to put more than one html table into a message sent with smtplib and... More on stackoverflow.com
Github style table
You might like the rich library. It creates nicely formatted tables.
https://github.com/Textualize/rich#readme
https://rich.readthedocs.io/en/latest/tables.html#tables
More on reddit.comVideos
DataCamp
datacamp.com › tutorial › python-tabulate
Python Tabulate: A Full Guide | DataCamp
September 5, 2024 - Multiple Output Formats: The tabulate ... text, HTML, LaTeX, and others; hence, users can choose according to the use case. Automatic Column Alignment: tabulate automatically aligns the columns of different data types, including strings, numbers, and others. Handling Various Data Structures: tabulate handles dictionaries, lists, pandas DataFrames, and NumPy arrays. You can use the pip package manager to install the tabulate package in Python...
Readthedocs
pyhdust.readthedocs.io › tabulate.html
tabulate: auxiliary module to tablature matrix — Python tools for the BeACoN group Stable documentation
headers="firstrow", tablefmt="html")) <table> <tr><th>strings </th><th style="text-align: right;"> numbers</th></tr> <tr><td>spam </td><td style="text-align: right;"> 41.9999</td></tr> <tr><td>eggs </td><td style="text-align: right;"> 451 </td></tr> </table> “latex” produces a tabular environment of LaTeX document markup: >>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], tablefmt="latex")) \begin{tabular}{lr} \hline spam & 41.9999 \\ eggs & 451 \\ \hline \end{tabular} “latex_booktabs” produces a tabular environment of LaTeX document markup using the booktabs.sty package: >>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], tablefmt="latex_booktabs")) \begin{tabular}{lr} \toprule spam & 41.9999 \\ eggs & 451 \\ \bottomrule \end{tabular}
Bitbucket
bitbucket.org › astanin › python-tabulate › issues › 57 › html-class-options-for-tables
astanin / python-tabulate / issues / #57 - HTML class options for tables — Bitbucket
June 26, 2015 - import tabulate from functools import partial def my_html_row_with_attrs(celltag, cell_values, colwidths, colaligns): alignment = { "left": '', "right": ' style="text-align: right;"', "center": ' style="text-align: center;"', "decimal": ' style="text-align: right;"' } values_with_attrs =\ ["<{0}{1} class=\"my-cell\">{2}</{0}>" .format(celltag, alignment.get(a, ''), c) for c, a in zip(cell_values, colaligns)] return "<tr class=\"my-row\">" + \ "".join(values_with_attrs).rstrip() + \ "</tr>" MyHTMLFormat = tabulate.TableFormat( lineabove=tabulate.Line("<table class=\"my-table\">", "", "", ""), l
GitHub
github.com › astanin › python-tabulate › issues › 44
HTML format with grid · Issue #44 · astanin/python-tabulate
March 12, 2020 - The existing "html" tablefmt produces good html tables but the are missing a border: Maybe a good idea will be to add a "grid_html" tablefmt to produce the exact same table but with borders:
Author arielszabo
Analytics Vidhya
analyticsvidhya.com › home › comprehensive guide to python’s tabulate library
Comprehensive Guide to Python's Tabulate Library - Analytics Vidhya
May 29, 2025 - Specify the desired table format using the `tablefmt` parameter (e.g., “grid”, “plain”, “html”, “markdown”): ... +---------+-----+------------------+ | Name | Age | Occupation | +---------+-----+------------------+ | Alice | 24 | Engineer | | Bob | 30 | Data Scientist | | Charlie | 27 | Designer | +---------+-----+------------------+ And that’s it! You’ve successfully created a basic table using the Tabulate library in Python.
Hanspeterschaub
hanspeterschaub.info › basilisk › Documentation › utilities › tabulate.html
tabulate — Basilisk 2.4.0 documentation
headers="firstrow", tablefmt="html")) <table> <tr><th>strings </th><th style="text-align: right;"> numbers</th></tr> <tr><td>spam </td><td style="text-align: right;"> 41.9999</td></tr> <tr><td>eggs </td><td style="text-align: right;"> 451 </td></tr> </table> “latex” produces a tabular environment of LaTeX document markup: >>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], tablefmt="latex")) \begin{tabular}{lr} \hline spam & 41.9999 \\ eggs & 451 \\ \hline \end{tabular} “latex_booktabs” produces a tabular environment of LaTeX document markup using the booktabs.sty package: >>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], tablefmt="latex_booktabs")) \begin{tabular}{lr} \toprule spam & 41.9999 \\ eggs & 451 \\ \bottomrule \end{tabular}
Python Central
pythoncentral.io › python-tabulate-creating-beautiful-tables-from-your-data
Python Tabulate: Creating Beautiful Tables from Your Data | Python Central
April 1, 2025 - Choose the Right Format: Select ... HTML) Limit Column Width: For better readability, consider truncating very long values · Headers: Always include headers for better data interpretation ... The tabulate library provides a simple yet powerful way to create beautiful tables in Python...
Copdips
copdips.com › 2018 › 07 › use-python-tabulate-module-to-create-tables.html
Use python tabulate module to create tables - A code to remember
July 28, 2018 - Html code can be injected into Markdown file. from tabulate import _table_formats, tabulate format_list = list(_table_formats.keys()) # current format list in tabulate version 0.8.3: # ['simple', 'plain', 'grid', 'fancy_grid', 'github', 'pipe', 'orgtbl', 'jira', 'presto', 'psql', 'rst', 'mediawiki', 'moinmoin', 'youtrack', 'html', 'latex', 'latex_raw', 'latex_booktabs', 'tsv', 'textile'] # Each element in the table list is a row in the generated table table = [["spam",42], ["eggs", 451], ["bacon", 0]] headers = ["item", "qty"] for f in format_list: print("\nformat: {}\n".format(f)) print(tabulate(table, headers, tablefmt=f))
Python for Network Engineers
pyneng.readthedocs.io › en › latest › book › 12_useful_modules › tabulate.html
tabulate - Python for network engineers
In [27]: print(tabulate(list_of_dict, headers='keys', tablefmt='pipe', stralign='center')) | Interface | IP | Status | Protocol | |:---------------:|:---------:|:--------:|:----------:| | FastEthernet0/0 | 15.0.15.1 | up | up | | FastEthernet0/1 | 10.0.12.1 | up | up | | FastEthernet0/2 | 10.0.13.1 | up | up | | Loopback0 | 10.1.1.1 | up | up | | Loopback100 | 100.0.0.1 | up | up |
GitHub
github.com › zackdever › python-tabulate › blob › master › tabulate.py
python-tabulate/tabulate.py at master · zackdever/python-tabulate
>>> print(tabulate([["strings", "numbers"], ["spam", 41.9999], ["eggs", "451.0"]], ... headers="firstrow", tablefmt="mediawiki")) {| class="wikitable" style="text-align: left;" |+ <!-- caption --> |- ! strings !! align="right"| numbers · |- | spam || align="right"| 41.9999 · |- | eggs || align="right"| 451 · |} · "html" produces HTML markup: ·
Author zackdever
Krbnite
krbnite.github.io › pretty-tables-in-pythonic-emails
Pretty Tables in Pythonic Emails
November 1, 2017 - python · wwe ] So you have a pandas DataFrame. Great! Now make it look pretty in a PDF file, or an email. How do you do it? The first way I figured out was to use the tabulate module. pip install tabulate · html_table = tabulate(df, headers=tbl.columns, tablefmt="html") text_tables= tabulate(tbl, headers=tbl.columns, tablefmt="grid") Then I found out you never really need to leave pandas!