How to show a pandas dataframe into a existing flask html table?
Solution 1
working example:
python code:
from flask import Flask, request, render_template, session, redirect
import numpy as np
import pandas as pd
app = Flask(__name__)
df = pd.DataFrame({'A': [0, 1, 2, 3, 4],
'B': [5, 6, 7, 8, 9],
'C': ['a', 'b', 'c--', 'd', 'e']})
@app.route('/', methods=("POST", "GET"))
def html_table():
return render_template('simple.html', tables=[df.to_html(classes='data')], titles=df.columns.values)
if __name__ == '__main__':
app.run(host='0.0.0.0')
html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% for table in tables %}
{{titles[loop.index]}}
{{ table|safe }}
{% endfor %}
</body>
</html>
or else use
return render_template('simple.html', tables=[df.to_html(classes='data', header="true")])
and remove {{titles[loop.index]}}
line from html
if you inspect element on html
<html lang="en"><head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body style="">
<table border="1" class="dataframe data">
<thead>
<tr style="text-align: right;">
<th></th>
<th>A</th>
<th>B</th>
<th>C</th>
</tr>
</thead>
<tbody>
<tr>
<th>0</th>
<td>0</td>
<td>5</td>
<td>a</td>
</tr>
<tr>
<th>1</th>
<td>1</td>
<td>6</td>
<td>b</td>
</tr>
<tr>
<th>2</th>
<td>2</td>
<td>7</td>
<td>c--</td>
</tr>
<tr>
<th>3</th>
<td>3</td>
<td>8</td>
<td>d</td>
</tr>
<tr>
<th>4</th>
<td>4</td>
<td>9</td>
<td>e</td>
</tr>
</tbody>
</table>
</body></html>
as you can see it has tbody and thead with in table html. so you can easily apply css.
Solution 2
In case anyone finds this helpful. I have gone with an alternative because I needed more customization, including the ability to add buttons in the table that performed actions. I also really don't like the standard table formatting as it is very ugly IMHO.
...
df = pd.DataFrame({'Patient Name': ["Some name", "Another name"],
"Patient ID": [123, 456],
"Misc Data Point": [8, 53]})
...
# link_column is the column that I want to add a button to
return render_template("patient_list.html", column_names=df.columns.values, row_data=list(df.values.tolist()),
link_column="Patient ID", zip=zip)
HTML Code: This Dynamically Converts any DF into a customize-able HTML table
<table>
<tr>
{% for col in column_names %}
<th>{{col}}</th>
{% endfor %}
</tr>
{% for row in row_data %}
<tr>
{% for col, row_ in zip(column_names, row) %}
{% if col == link_column %}
<td>
<button type="submit" value={{ row_ }} name="person_id" form="patient_form" class="patient_button">
{{ row_ }}
</button>
</td>
{% else %}
<td>{{row_}}</td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}
</table>
CSS Code
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
It performs very well and it looks WAY better than the .to_html
output.
Solution 3
# Declare table
class SomeTable(Table):
status = Col('Customer')
city = Col('City')
product_price = Col('Country')
# Convert the pandas Dataframe into dictionary structure
output_dict = output.to_dict(orient='records')
# Populate the table
table = SomeTable(output_dict)
return (table.__html__())
or as pandas return static HTML file you can render it as page using Flask
@app.route('/<string:filename>/')
def render_static(filename):
return render_template('%s.html' % filename)
It's the Idea of how we can do it in Flask. Hope you can understand this and let me know if it's not helping!
Update:
import pandas as pd
df = pd.DataFrame({'col1': ['abc', 'def', 'tre'],
'col2': ['foo', 'bar', 'stuff']})
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return df.to_html(header="true", table_id="table")
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
But I'd go with Flask HTML feature rather than DataFrame to HTML (due to styling)
Solution 4
For those looking for a simple/succinct example of taking a Pandas df and turning into a Flask/Jinja table (which is the reason I ended up on this question):
APP.PY -- APPLICATION FACTORY:
## YOUR DF LOGIC HERE
@app.route("/")
def home():
return render_template('index.html' column_names=df.columns.values, row_data=list(df.values.tolist()), zip=zip)
Your static template (e.g. index.html)
<table>
<thead>
<tr>
{% for col in column_names %}
<th>
{{col}}
</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for row in row_data %}
<tr>
{% for col, row_ in zip(column_names, row) %}
<td>{{row_}}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
Solution 5
For me using Jinja's for loop
{% for table in tables %}
{{titles[loop.index]}}
{{ table|safe }}
{% endfor %}
didnt work as it simply printed each character 1 by 1. I simply had to use
{{ table|safe }}
Motta
"Hello World" My name is João Victor, I'm 25 years old and a IoT and Big Data passionate. I've started my programming developer story at my first company, when I was 17 years old. It was my first experience and Microsoft Excel my first friend. With two months using the tool, I discovered the VBA magic, and I got amazed by what can be done with it. Then PHP, SQL, HTML, JAVA and JavaScript were being added to my life once my curiosity grew! What a great moment to be alive! End Sub
Updated on July 09, 2022Comments
-
Motta almost 2 years
This may sound a noob question, but I'm stuck with it as Python is not one of my best languages.
I have a html page with a table inside it, and I would like to show a pandas dataframe in it. What is the best way to do it? Use pandasdataframe.to_html?
py
from flask import Flask; import pandas as pd; from pandas import DataFrame, read_csv; file = r'C:\Users\myuser\Desktop\Test.csv' df = pd.read_csv(file) df.to_html(header="true", table_id="table")
html
<div class="table_entrances" style="overflow-x: auto;"> <table id="table"> <thead></thead> <tr></tr> </table> </div>
-
Motta over 5 yearswhat about the html code? should I not give him an Id in order to load this table at a correct position of my webpage? Or even to update it when a new dataframe come?
-
Chandu over 5 yearsYou can leave the HTML code just make a function that return
df.to_html
another function which will render the html in the web. -
Umar.H about 5 yearsThanks, Nihal, working through a python webapp course and we were told to experiment with our first build. The first thing that came to mind was to display a dataframe on a website. Worked wonderfully (although ugly without css!)
-
Kshitij Yadav almost 5 yearsIf we use HTML code, where do we need to put it? Next to dockerfile?
-
user101 almost 5 yearsAny idea on how to not display the row indices?
-
Nihal almost 5 yearsfrom df drop index before rendering it.
-
Nihal almost 5 yearsuse
df.to_html(index = False)
-
Mikee over 4 years@Nihal, the html you posted is truncating some columns' contents. How do I work around this problem?
-
Nihal over 4 years@user1783739 can you please give an example of your problem? or ask question and post like here.
-
David Gladson over 4 yearsany idea why do we use 'safe'? what does 'table|safe' mean & what does it do?
-
David Gladson over 4 yearsany idea why do we use 'safe'? what does 'table|safe' mean & what does it do?
-
Biarys over 4 years@DavidGladson The safe filter explicitly marks a string as "safe", i.e., it should not be automatically-escaped if auto-escaping is enabled. More on that in docs jinja.palletsprojects.com/en/2.10.x/templates/… and this SO stackoverflow.com/questions/12341496/jinja-2-safe-keyword
-
Nihal over 4 years@DavidGladson check this link
-
gumdropsteve almost 3 yearswhere would I put the css? file name?