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
🌐
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’.
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

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
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
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
Using tabulate prints string instead of html file
Which template engine are you using? Could be Django Templates or Jinja. More on reddit.com
🌐 r/learnpython
4
1
August 30, 2021
🌐
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...
🌐
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
🌐
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
🌐
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.
Find elsewhere
🌐
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.
🌐
Packetswitch
packetswitch.co.uk › how-to-create-tables-python-tabulate-module
How to Create Tables with Python Tabulate Module
April 26, 2024 - In the script, the different tablefmt ... grid lines between rows and columns for a more structured look. tablefmt="HTML" - Generates the table in HTML format, which is useful for web pages or HTML documents....
🌐
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!
🌐
AITechTrend
aitechtrend.com › from-messy-data-to-polished-tables-how-tabulate-can-help-you-in-your-python-projects
From Messy Data to Polished Tables: How Tabulate Can Help You in Your Python Projects - AITechTrend
February 25, 2023 - Tabulate is a Python package that allows you to create nicely formatted tables in a variety of formats, including Markdown, HTML, and LaTeX.
🌐
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   astanin
🌐
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}
🌐
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
🌐
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}
🌐
Reddit
reddit.com › r/learnpython › using tabulate prints string instead of html file
r/learnpython on Reddit: Using tabulate prints string instead of html file
August 30, 2021 -

Hey guys,

I am trying to work through building a webapp for a personal project and mainly just to learn how to do it. I have functions set up to webscrape some data, which is stored in a SQLite database. I pull in the data from the databases fine, which is given as a list of lists. From there I am trying to use "tabulate" which works fine in my jupyter notebook to form a table as a test, and when I print the output it gives me my html formatted code.

The issue is when I try to display it in my webapp by trying:

{% extends "base.html" %} {% block title %}Home{% endblock %} {% block content%}

{% print(var1) %}

{% endblock %}

Where var1 is:

conn = sqlite3.connect(r"directorystring\database.db")

cur = conn.cursor()var = cur.execute("SELECT * from Table1").fetchall()

var1= tabulate(var, tablefmt='html')

I've also tried {{ var1 }} instead of {% print(var1) %} and every other combination I can think of but all it does is either display a blank webpage or the actual string of html code <table> <tbody> <tr><td>Entry 1</td><td style="text-align: right;">... etc

Firstly, is using tabulate a good way of going about it, and is there a better/easier way to post a data table from sqlite to html? Secondly does anyone have any idea what I'm doing wrong?! I hope I've included the correct parts of the code.

Thanks!

EDIT: sorry for the formatting i've tried several times to get it working properly, i've even copied from the markdown wiki and it still won't work!

🌐
Decalage
decalage.info › python › html
HTML.py - a Python module to easily generate HTML tables and lists | Decalage
Michal, I've improved HTML.py thanks to your ideas and code proposal. The Table class in HTML.py 0.04 provides new attributes to set width, alignment and style for each column.