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

Python通过Gmail发送邮件时DataFrame条件格式无法保留的问题求助

问题:DataFrame条件格式在Gmail邮件正文中丢失

我有一个按特定规则设置了条件格式的DataFrame,尝试通过Gmail以邮件正文(非附件)形式发送后,条件格式完全丢失了,请问问题出在哪里?

DataFrame 代码

import pandas as pd

df = pd.DataFrame({'Reference': ['40%','30%'],
                   'colA': ['30% (20%)','25% (14%)'],
                   'colB': ['45% (20%)','25% (30%)'],
                   'colC': ['25% (30%)','35% (30%)']})

格式化DataFrame代码

def highlight(x, color1, color2):
    reference = x[0]
    ans = [None]
    for y in x[1:]:
        c = color1 if y < reference else color2
        ans.append(f"background-color: {c};")
    return ans

df = df.style.apply(highlight, color1='green', color2='red', axis=1)

邮件发送代码

from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from smtplib import SMTP
import smtplib
import sys


recipients = ['abc@xyz.com'] 
emaillist = [elem.strip().split(',') for elem in recipients]
msg = MIMEMultipart()
msg['Subject'] = "Information"
msg['From'] = 'abc@gmail.com'

html = """\
<html>
  <head></head>
  <body>
    {0}
  </body>
</html>
""".format(df.to_html())

part1 = MIMEText(html, 'html')
msg.attach(part1)

server = smtplib.SMTP('smtp.gmail.com', 587)
server.ehlo()

server.starttls()

server.login('abc@gmail.com', 'etehdnwyrfzgwwze')
server.sendmail(msg['From'], emaillist , msg.as_string())

问题原因及解决方法

核心问题

  1. 字符串比较逻辑错误:直接用带格式的百分比字符串(如'30% (20%)')和参考值(如'40%')做大小比较,是按ASCII码顺序判断的,和实际数值大小逻辑完全不符。比如'25% (30%)'字符串和'30%'的比较结果,并不是基于数值的,导致高亮规则完全失效。
  2. 变量覆盖问题:原代码中用df = df.style.apply(...)覆盖了原始DataFrame,虽然不影响样式生成,但容易造成混淆,建议单独命名样式对象。

修复步骤

1. 修正数值比较逻辑

从字符串中提取括号外的百分比数值,转为浮点数后再做大小判断:

def extract_percent(s):
    # 提取括号前的百分比数值,去除%符号后转成浮点数
    return float(s.split('(')[0].strip().replace('%', ''))

def highlight(x, color1, color2):
    reference_val = extract_percent(x[0])
    ans = [None]  # Reference列不添加背景色
    for y in x[1:]:
        y_val = extract_percent(y)
        c = color1 if y_val < reference_val else color2
        ans.append(f"background-color: {c};")
    return ans

# 单独存储样式对象,不覆盖原始DataFrame
df_styled = df.style.apply(highlight, color1='green', color2='red', axis=1)

2. 优化邮件发送代码

  • 简化收件人列表处理,添加To邮件头使显示更规范
  • 确保关闭SMTP连接,避免资源占用
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import smtplib

recipients = ['abc@xyz.com'] 
msg = MIMEMultipart()
msg['Subject'] = "Information"
msg['From'] = 'abc@gmail.com'
msg['To'] = ', '.join(recipients)  # 添加To头

html = """\
<html>
  <head></head>
  <body>
    {0}
  </body>
</html>
""".format(df_styled.to_html())

part1 = MIMEText(html, 'html')
msg.attach(part1)

server = smtplib.SMTP('smtp.gmail.com', 587)
server.ehlo()
server.starttls()
# 注意:如果开启了两步验证,需要使用Gmail应用专用密码
server.login('abc@gmail.com', 'etehdnwyrfzgwwze')
server.sendmail(msg['From'], recipients, msg.as_string())
server.quit()  # 关闭连接

3. 验证样式生成

可以先打印print(df_styled.to_html()),查看表格的<td>标签是否包含正确的style="background-color: green;"或red属性,确认样式生成正确后再发送邮件。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 03:41:20