You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python如何拼接两个带表头DataFrame写入CSV并生成美观邮件正文表格

可直接适配的实现方案

不需要修改你现有send_mail、smtplib、email系列模块、configparser相关的已有逻辑,分两部分实现需求:


1. 生成指定格式的CSV附件

不要直接拼接两个DataFrame写入,通过内存流按要求插入分段标识,无需生成本地临时文件,直接适配MIMEApplication附件逻辑:

import pandas as pd
from io import StringIO, BytesIO

# 初始化内存文本流写CSV内容
csv_buf = StringIO()
# 写入df1分段
csv_buf.write("The Errors in df1 are:\n")
df1.to_csv(csv_buf, index=False, header=True, encoding="utf-8")
csv_buf.write("\n") # 空行分隔两段,避免内容粘连
# 写入df2分段
csv_buf.write("The Errors in df2 are:\n")
df2.to_csv(csv_buf, index=False, header=True, encoding="utf-8")

# 转成带BOM的utf-8字节流,适配Excel直接打开不乱码
csv_bytes = BytesIO(csv_buf.getvalue().encode("utf-8-sig"))
# 把csv_bytes传入你现有send_mail的附件参数即可,原有附件处理逻辑完全不用改

生成的CSV完全符合格式要求:先输出df1的标识行,再带表头输出df1全量数据,空行分隔后输出df2标识行和带表头的df2全量数据。


2. 生成高可读性邮件正文表格

之前用tabulate生成纯文本表格排版混乱,是因为不同邮件客户端的等宽字体渲染规则不一致,很容易出现列错位、文字拥挤的问题。既然你已经支持HTML格式的MIMEText正文,直接用pandas原生的to_html方法加内联CSS样式即可,无额外第三方依赖,所有主流邮件客户端(Outlook、网页邮箱、移动端邮箱)都能正常渲染,不会出现排版错乱:

# 表格基础样式:加内边距、边框、隔行变色,彻底解决拥挤问题
html_style = """
<style>
.err-section {
    font-size: 15px;
    font-weight: bold;
    margin: 16px 0 8px;
    font-family: "Microsoft Yahei", sans-serif;
}
.err-table {
    border-collapse: collapse;
    width: 100%;
    font-family: "Microsoft Yahei", sans-serif;
    font-size: 14px;
}
.err-table th {
    background-color: #f0f0f0;
    border: 1px solid #ccc;
    padding: 8px 12px;
    text-align: left;
}
.err-table td {
    border: 1px solid #ccc;
    padding: 8px 12px;
}
</style>
"""

# 正文结构模板
html_body = """
<html>
<body>
    <p style="font-family: 'Microsoft Yahei', sans-serif; font-size: 14px;">
        本次任务运行检测到如下错误数据,请及时处理:
    </p>
    <div class="err-section">The Errors in df1 are:</div>
    {df1_tbl}
    <div class="err-section">The Errors in df2 are:</div>
    {df2_tbl}
</body>
</html>
"""

# 把两个DataFrame转成带指定样式类的HTML表格,去掉pandas默认冗余边框属性,加隔行变色逻辑
df1_tbl_html = df1.to_html(index=False, classes="err-table", border=0)
# 给表格插入隔行变色样式
df1_tbl_html = df1_tbl_html.replace("<tr>", '<tr style="background-color: #fafafa;">', 1)
for i in range(3, len(df1)+2, 2):
    df1_tbl_html = df1_tbl_html.replace("<tr>", '<tr style="background-color: #fafafa;">', i)

df2_tbl_html = df2.to_html(index=False, classes="err-table", border=0)
df2_tbl_html = df2_tbl_html.replace("<tr>", '<tr style="background-color: #fafafa;">', 1)
for i in range(3, len(df2)+2, 2):
    df2_tbl_html = df2_tbl_html.replace("<tr>", '<tr style="background-color: #fafafa;">', i)

# 拼接最终HTML正文
final_mail_html = html_style + html_body.format(df1_tbl=df1_tbl_html, df2_tbl=df2_tbl_html)
# 把final_mail_html传入你现有send_mail的正文参数,构造MIMEText时指定subtype='html'即可,原有逻辑无需修改

该方案的排版优势:

  • 单元格设置了左右12px、上下8px的内边距,不会出现文字紧贴边框的拥挤问题
  • 加了浅灰色边框和隔行变色,行与行区分度高,长表格阅读不容易串行
  • 宽度自适应邮件窗口,不会出现横向滚动条或者列宽被压缩的问题
  • 样式全部内联在HTML代码中,不会被邮件客户端的安全策略过滤

调用现有send_mail函数时,直接传入final_mail_html作为HTML正文、csv_bytes作为CSV附件即可,不需要调整你已经编写完成的smtplib连接、configparser配置读取、MIME构造相关的任何代码。

内容的提问来源于stack exchange,提问作者unicorn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 02:51:26