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 Overflow
🌐
PyPI
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
    
Published   Mar 04, 2026
Version   0.10.0
Top answer
1 of 1
1

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)
Discussions

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
🌐 github.com
4
March 12, 2020
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
🌐 stackoverflow.com
March 18, 2019
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
🌐 stackoverflow.com
August 20, 2018
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.com
🌐 r/learnpython
2
1
February 20, 2022
🌐
AskPython
askpython.com › home › python tabulate module: how to easily create tables in python?
Python tabulate module: How to Easily Create Tables in Python? - AskPython
June 8, 2023 - To enhance the look of your table, use the tablefmt attribute and set it to grid for a bordered table, or fancy_grid for a more sophisticated border. If you need the HTML code, set tablefmt to ‘html’.
🌐
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
Find elsewhere
🌐
Medium
medium.com › @HeCanThink › tabulate-your-go-to-solution-for-stylish-tables-in-python-35ede5145e28
Tabulate: Your Go-To Solution for Stylish Tables in Python 👉 | by Manoj Das | Medium
August 19, 2023 - Some common formatting styles include plain text, simple, grid, pipe, html, and latex. The Tabulate library was developed to address the need for easily creating formatted tables from various data sources in Python.
🌐
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}
🌐
GeeksforGeeks
geeksforgeeks.org › python › introduction-to-python-tabulate-library
Introduction to Python Tabulate Library - GeeksforGeeks
July 23, 2025 - Customizable Table Formats: The tabulate module supports various formats for tables, such as plain text, grid, markdown, HTML, and more.
🌐
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!
🌐
LearnPython.com
learnpython.com › blog › print-table-in-python
How to Pretty-Print Tables in Python | LearnPython.com
When you finish the exploratory data analysis phase, you may want to make your tables look nicer. Two libraries provide the functionality to pretty print comma-separated values (CSV) in Python: tabulate and prettytable.