大家好,在我们的Streamlit交流群中经常听到小伙伴们吐槽Streamlit自带的表格样式太不友好了,不仅布局不好,如表格内容无法全部显示出来、每列的内容无法居中显示、主题色也不好看、表格行数信息从0开始不符合大家习惯等。
针对这个问题,作者今天花了一上午的时间,摸索了一下基于Bootrap框架的表格美化方案,支持直接显示pandas.dataframe对象,在这里把实现方法分享给大家,如果大家觉得还不错的话,快快分享给身边的小伙伴哦!
今天的实现效果
今天的实现代码
import streamlit as st
import pandas as pd
import streamlit.components.v1 as components
st.set_page_config(page_title="基于Bootstrap的表格展示案例", page_icon="🅱️", layout="wide")
def draw_table(df, theme, table_height):
columns = df.columns
thead1="""<thead><th scope="col"></th>"""
thead_temp = []
for k in range(len(list(columns))):
thead_temp.append("""<th scope="col" class="text-white">"""+str(list(columns)[k])+"""</th>""")
header = thead1+"".join(thead_temp)+"""</tr></thead>"""
rows = []
rows_temp = []
for i in range(df.shape[0]):
rows.append("""<th scope="row">"""+str(i+1)+"""</th>""")
rows_temp.append(df.iloc[i].values.tolist())
td_temp = []
for j in range(len(rows_temp)):
for m in range(len(rows_temp[j])):
td_temp.append("""<td class="text-white">"""+str(rows_temp[j][m])+"""</td>""")
td_temp2 = []
for n in range(len(td_temp)):
td_temp2.append(td_temp[n:n+df.shape[1]])
td_temp3 = []
for x in range(len(td_temp2)):
if int(x % (df.shape[1])) == 0:
td_temp3.append(td_temp2[x])
td_temp4 = []
for xx in range(len(td_temp3)):
td_temp4.append("".join(td_temp3[xx]))
td_temp5 = []
for v in range(len(td_temp4)):
td_temp5.append("""<tr><th scope="row" class="text-white">"""+str(v+1)+"""</th>"""+str(td_temp4[v])+"""</tr>""")
table_html = """<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">"""+\
"""<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>"""+\
"""<table class="table text-center table-bordered """+str(theme)+'"'+">""" + \
header+"""<tbody>"""+"".join(td_temp5)+"""</tbody></table>"""
return components.html(table_html,height=table_height, scrolling=True)
st.header("基于Bootstrap的表格样式展示案例")
file = st.file_uploader("请上传csv表格")
if file is not None:
df = pd.read_csv(file, encoding="gbk")
theme_list=["bg-primary", "bg-success", "bg-warning", "bg-danger", "bg-info", "table-dark"]
theme = st.selectbox("请选择一种主题", theme_list)
draw_table(df, theme=theme, table_height=300)
st.sidebar.header("Streamlit自带的表格样式")
st.sidebar.info("st.write")
st.sidebar.write(df)
st.sidebar.info("st.table")
st.sidebar.table(df)
st.sidebar.info("st.dataframe")
st.sidebar.dataframe(df)
实现原理
1、本文案例得以实现,依赖的第一个组件为
import streamlit.components.v1 as components
这个组件支持我们直接输入html代码,然后在浏览器中显示出来
基本用法如下:
import streamlit.components.v1 as components
components.html("""我们要使用的HTML代码""", weight=500, height=300, scrolling=True)
2、我们参考Bootstrap的表格代码,确定好基本的表格框架,如下面这种
<table class="table table-dark">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">First</th>
<th scope="col">Last</th>
<th scope="col">Handle</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
从上面可以看出,我们要用的表头是在与之间的,每一行的内容分别位于与之间的。
3、弄清楚了表格基础结构后,我们要做的就是一步一步的构建出我们需要的内容,本案例中,作者的创新之处在于,使得直接显示dataframe对象成为了可能,同时可以设置表格主题、表格高度,核心功能通过下面这个函数完成,这个函数的实现花费了最多的时间,过程曲折,动脑筋解决问题的过程还是蛮享受的。
def draw_table(df, theme, table_height):
columns = df.columns
thead1="""<thead><th scope="col"></th>"""
thead_temp = []
for k in range(len(list(columns))):
thead_temp.append("""<th scope="col" class="text-white">"""+str(list(columns)[k])+"""</th>""")
header = thead1+"".join(thead_temp)+"""</tr></thead>"""
rows = []
rows_temp = []
for i in range(df.shape[0]):
rows.append("""<th scope="row">"""+str(i+1)+"""</th>""")
rows_temp.append(df.iloc[i].values.tolist())
td_temp = []
for j in range(len(rows_temp)):
for m in range(len(rows_temp[j])):
td_temp.append("""<td class="text-white">"""+str(rows_temp[j][m])+"""</td>""")
td_temp2 = []
for n in range(len(td_temp)):
td_temp2.append(td_temp[n:n+df.shape[1]])
td_temp3 = []
for x in range(len(td_temp2)):
if int(x % (df.shape[1])) == 0:
td_temp3.append(td_temp2[x])
td_temp4 = []
for xx in range(len(td_temp3)):
td_temp4.append("".join(td_temp3[xx]))
td_temp5 = []
for v in range(len(td_temp4)):
td_temp5.append("""<tr><th scope="row" class="text-white">"""+str(v+1)+"""</th>"""+str(td_temp4[v])+"""</tr>""")
table_html = """<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">"""+\
"""<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>"""+\
"""<table class="table text-center table-bordered """+str(theme)+'"'+">""" + \
header+"""<tbody>"""+"".join(td_temp5)+"""</tbody></table>"""
return components.html(table_html,height=table_height, scrolling=True)
这个函数内部,大家可以不用理会,有耐心的小伙伴可以拆解后一步步理解一下,此函数为本文作者100%原创,大家可以直接复制使用,具体使用的时候,使用方法如下:
file = st.file_uploader("请上传csv表格")
if file is not None:
df = pd.read_csv(file, encoding="gbk")
theme_list=["bg-primary", "bg-success", "bg-warning", "bg-danger", "bg-info", "table-dark"]
theme = st.selectbox("请选择一种主题", theme_list)
draw_table(df, theme=theme, table_height=300)
4、作者从Bootstrap文档中找了这几种主题供大家参考:
theme_list=["bg-primary", "bg-success", "bg-warning", "bg-danger", "bg-info", "table-dark"]
Streamlit交流群
你开始学习Streamlit了吗,学习中有没有遇到什么问题,如果你期待和其他热爱学习的朋友们一起交流、学习编程相关内容的话,
欢迎关注作者,学习更多实用的Python案例!
如果你觉得本文还不错的话,请点赞、分享给身边的朋友们哦,谢谢!