在pandas 1.3.0 及更新版本中,最合适的方式是使用pandas Table Visualization 并创建一个Subclass
创建一个文件夹“templates”和两个文件“myhtml.tpl”和“mystyles.tpl”
在 myhtml.tpl 中添加所需的任何额外 HTML 代码:
{% extends "html_table.tpl" %}
{% block table %}
<p style="font-family:verdana">Hi,</p>
<p style="font-family:verdana">sometext</p>
{{ super() }}
<p style="font-family:verdana">sometext</p>
<p style="font-family:verdana">Regards</p>
<p style="font-family:verdana">someme</p>
{% endblock table %}
在 mystyles.tpl 添加任何其他样式:
{% extends "html_style.tpl" %}
{% block style %}
{{ super() }}
<style>
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
th, td {
padding: 5px;
}
</style>
{% endblock style %}
(生成此文件结构的代码在此答案的末尾)
我们现在可以使用from_custom_template 生成Styler 子类
import numpy as np
import pandas as pd
from pandas.io.formats.style import Styler
# Build Styler Subclass from templates
MyStyler = Styler.from_custom_template(
"templates", # Folder to Search
html_table="myhtml.tpl", # HTML Template
html_style='mystyles.tpl' # CSS Template
)
# trim extra whitespace from HTML
MyStyler.env.trim_blocks = True
# Read in CSV
df = pd.read_csv('files/file.csv')
# Add styles using Styler apply and render to_html
html = MyStyler(df).apply(
lambda s: np.where(s >= 80, 'color: red', None), subset='Usage in %'
).format(
# Apply format string (remove insignificant zeros)
formatter='{:g}', subset='Usage in %'
).hide_index().to_html(doctype_html=True)
print(html)
生成的 html 字符串类似于:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style type="text/css">
#T_22fdb_row2_col3,
#T_22fdb_row3_col3 {
color: red;
}
</style>
<style>
table,
th,
td {
border: 1px solid black;
border-collapse: collapse;
}
th,
td {
padding: 5px;
}
</style>
</head>
<body>
<p style="font-family:verdana">Hi,</p>
<p style="font-family:verdana">sometext</p>
<table id="T_22fdb_">
<thead>
<tr>
<th class="col_heading level0 col0">Server</th>
<th class="col_heading level0 col1">Total size</th>
<th class="col_heading level0 col2">Total Data in</th>
<th class="col_heading level0 col3">Usage in %</th>
</tr>
</thead>
<tbody>
<tr>
<td id="T_22fdb_row0_col0" class="data row0 col0">A</td>
<td id="T_22fdb_row0_col1" class="data row0 col1">100</td>
<td id="T_22fdb_row0_col2" class="data row0 col2">25</td>
<td id="T_22fdb_row0_col3" class="data row0 col3">25</td>
</tr>
<tr>
<td id="T_22fdb_row1_col0" class="data row1 col0">B</td>
<td id="T_22fdb_row1_col1" class="data row1 col1">100</td>
<td id="T_22fdb_row1_col2" class="data row1 col2">20</td>
<td id="T_22fdb_row1_col3" class="data row1 col3">20</td>
</tr>
<tr>
<td id="T_22fdb_row2_col0" class="data row2 col0">C</td>
<td id="T_22fdb_row2_col1" class="data row2 col1">100</td>
<td id="T_22fdb_row2_col2" class="data row2 col2">85</td>
<td id="T_22fdb_row2_col3" class="data row2 col3">85.6</td>
</tr>
<tr>
<td id="T_22fdb_row3_col0" class="data row3 col0">D</td>
<td id="T_22fdb_row3_col1" class="data row3 col1">100</td>
<td id="T_22fdb_row3_col2" class="data row3 col2">90</td>
<td id="T_22fdb_row3_col3" class="data row3 col3">90.8</td>
</tr>
</tbody>
</table>
<p style="font-family:verdana">sometext</p>
<p style="font-family:verdana">Regards</p>
<p style="font-family:verdana">someme</p>
</body>
</html>
解决这个问题的更简单的方法是直接使用格式化操作 html 字符串,但是,这可能会导致 html 格式不正确:
import numpy as np
import pandas as pd
html = """
<html>
<head>
<style>
table, th, td {{ border: 1px solid black; border-collapse: collapse; }}
th, td {{ padding: 5px; }}
</style>
</head>
<body><p style="font-family:verdana">Hi,</p>
<p style="font-family:verdana">sometext</p>
{table}
<p style="font-family:verdana">sometext</p>
<p style="font-family:verdana">Regards</p>
<p style="font-family:verdana">someme</p>
</body></html>
"""
# Read in CSV
df = pd.read_csv('files/file.csv')
# Add styles using Styler apply and render to_html
table_html = df.style.apply(
lambda s: np.where(s >= 80, 'color: red', None), subset='Usage in %'
).format(
# Apply format string (remove insignificant zeros)
formatter='{:g}', subset=['Total Data in', 'Usage in %']
).hide_index().to_html()
html = html.format(table=table_html)
print(html)
这会导致以下 html(注意样式元素放错位置):
<html>
<head>
<style>
table, th, td { border: 1px solid black; border-collapse: collapse; }
th, td { padding: 5px; }
</style>
</head>
<body><p style="font-family:verdana">Hi,</p>
<p style="font-family:verdana">sometext</p>
<style type="text/css">
#T_139a3_row2_col3, #T_139a3_row3_col3 {
color: red;
}
</style>
<table id="T_139a3_">
<thead>
<tr>
<th class="col_heading level0 col0" >Server</th>
<th class="col_heading level0 col1" >Total size</th>
<th class="col_heading level0 col2" >Total Data in</th>
<th class="col_heading level0 col3" >Usage in %</th>
</tr>
</thead>
<tbody>
<tr>
<td id="T_139a3_row0_col0" class="data row0 col0" >A</td>
<td id="T_139a3_row0_col1" class="data row0 col1" >100</td>
<td id="T_139a3_row0_col2" class="data row0 col2" >25</td>
<td id="T_139a3_row0_col3" class="data row0 col3" >25</td>
</tr>
<tr>
<td id="T_139a3_row1_col0" class="data row1 col0" >B</td>
<td id="T_139a3_row1_col1" class="data row1 col1" >100</td>
<td id="T_139a3_row1_col2" class="data row1 col2" >20</td>
<td id="T_139a3_row1_col3" class="data row1 col3" >20</td>
</tr>
<tr>
<td id="T_139a3_row2_col0" class="data row2 col0" >C</td>
<td id="T_139a3_row2_col1" class="data row2 col1" >100</td>
<td id="T_139a3_row2_col2" class="data row2 col2" >85</td>
<td id="T_139a3_row2_col3" class="data row2 col3" >85.6</td>
</tr>
<tr>
<td id="T_139a3_row3_col0" class="data row3 col0" >D</td>
<td id="T_139a3_row3_col1" class="data row3 col1" >100</td>
<td id="T_139a3_row3_col2" class="data row3 col2" >90</td>
<td id="T_139a3_row3_col3" class="data row3 col3" >90.8</td>
</tr>
</tbody>
</table>
<p style="font-family:verdana">sometext</p>
<p style="font-family:verdana">Regards</p>
<p style="font-family:verdana">someme</p>
</body></html>
构建模板文件夹和两个模板文件的简单脚本:
import pathlib
# Code to generate the Templates and folder
pathlib.Path('./templates').mkdir(exist_ok=True)
with open('./templates/myhtml.tpl', 'w') as f:
f.write('''
{% extends "html_table.tpl" %}
{% block table %}
<p style="font-family:verdana">Hi,</p>
<p style="font-family:verdana">sometext</p>
{{ super() }}
<p style="font-family:verdana">sometext</p>
<p style="font-family:verdana">Regards</p>
<p style="font-family:verdana">someme</p>
{% endblock table %}
'''.strip())
with open('./templates/mystyles.tpl', 'w') as f:
f.write('''
{% extends "html_style.tpl" %}
{% block style %}
{{ super() }}
<style>
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
th, td {
padding: 5px;
}
</style>
{% endblock style %}
'''.strip())
files/file.csv 内容:
Server,Total size,Total Data in,Usage in %
A,100,25,25
B,100,20,20
C,100,85,85.6
D,100,90,90.8