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

生成邮件附件Excel时如何合并BDName与BDEmail的重复列值

解决Excel重复字段合并显示并作为邮件附件发送的问题

我来帮你搞定这个需求——生成带有重复BDName/BDEmail合并显示效果的Excel,再把它作为邮件附件发出去。下面用Python给你两种实用的实现方案,都是日常项目里常用的思路:

方法一:Pandas预处理+Openpyxl合并单元格(适合大数据量)

先通过Pandas标记重复行,再用Openpyxl实现单元格合并,视觉效果更规整:

步骤1:预处理数据,标记重复项

先把原始数据里重复的BDName和BDEmail标记出来,重复行的对应字段设为空:

import pandas as pd

# 假设你的原始数据是这种列表格式
raw_data = [
    {"BDName": "siva", "BDEmail": "a@a.com", "Process Id": "a1", "Customer Name": "hari", "Email": "h@h.com"},
    {"BDName": "siva", "BDEmail": "a@a.com", "Process Id": "a2", "Customer Name": "hari", "Email": "h@h.com"},
    {"BDName": "john", "BDEmail": "j@j.com", "Process Id": "b1", "Customer Name": "lisa", "Email": "l@l.com"},
    {"BDName": "john", "BDEmail": "j@j.com", "Process Id": "b2", "Customer Name": "mike", "Email": "m@m.com"},
]

df = pd.DataFrame(raw_data)
# 标记当前行的BD信息是否和上一行完全重复
df['is_duplicate'] = (df['BDName'] == df['BDName'].shift(1)) & (df['BDEmail'] == df['BDEmail'].shift(1))
# 重复行的BD字段设为空,只保留第一行的值
df.loc[df['is_duplicate'], ['BDName', 'BDEmail']] = ''

步骤2:生成Excel并合并重复单元格

用Openpyxl读取Pandas导出的临时文件,合并相同值的单元格:

from openpyxl import load_workbook
from openpyxl.styles import Alignment
from openpyxl.utils import get_column_letter

# 导出临时Excel
temp_file = "temp_bd_data.xlsx"
df.to_excel(temp_file, index=False)

# 加载文件并处理合并
wb = load_workbook(temp_file)
ws = wb.active

# 设置单元格垂直居中,提升美观度
for row in ws.iter_rows():
    for cell in row:
        cell.alignment = Alignment(vertical='center', horizontal='center')

# 合并BDName和BDEmail列的重复单元格
start_row = 2  # 表头在第1行,从第2行开始处理
prev_bd_key = (ws['A2'].value, ws['B2'].value)

for row_num in range(3, ws.max_row + 1):
    current_bd_key = (ws[f'A{row_num}'].value, ws[f'B{row_num}'].value)
    if current_bd_key == ('', ''):
        continue
    else:
        if start_row != row_num - 1:
            ws.merge_cells(f'A{start_row}:A{row_num - 1}')
            ws.merge_cells(f'B{start_row}:B{row_num - 1}')
        prev_bd_key = current_bd_key
        start_row = row_num
# 处理最后一组重复项
if start_row != ws.max_row:
    ws.merge_cells(f'A{start_row}:A{ws.max_row}')
    ws.merge_cells(f'B{start_row}:B{ws.max_row}')

# 保存最终文件
final_excel = "bd_business_report.xlsx"
wb.save(final_excel)

步骤3:作为邮件附件发送

用Python内置的邮件库实现发送:

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders

# 邮件配置信息,替换成你自己的
sender = "your_email@example.com"
receiver = "target_email@example.com"
password = "your_email_password_or_app_code"
smtp_server = "smtp.example.com"
smtp_port = 587

# 构建邮件
msg = MIMEMultipart()
msg['From'] = sender
msg['To'] = receiver
msg['Subject'] = "最新BD业务数据报表"

# 添加正文
body = "您好,附件是最新的BD业务数据,请查收。"
msg.attach(MIMEText(body, 'plain'))

# 添加附件
with open(final_excel, "rb") as f:
    part = MIMEBase('application', 'octet-stream')
    part.set_payload(f.read())
encoders.encode_base64(part)
part.add_header('Content-Disposition', f'attachment; filename="{final_excel}"')
msg.attach(part)

# 发送邮件
with smtplib.SMTP(smtp_server, smtp_port) as server:
    server.starttls()
    server.login(sender, password)
    server.send_message(msg)
print("邮件发送成功!")

方法二:直接用Openpyxl逐行写入(适合小数据量)

如果数据量不大,也可以直接逐行写入时判断重复,重复的BD字段留空:

from openpyxl import Workbook
from openpyxl.styles import Alignment

# 创建工作簿
wb = Workbook()
ws = wb.active

# 写入表头
headers = ["BDName", "BDEmail", "Process Id", "Customer Name", "Email"]
ws.append(headers)
# 设置表头样式
for cell in ws[1]:
    cell.alignment = Alignment(vertical='center', horizontal='center')
    cell.font = cell.font.copy(bold=True)

# 逐行写入并处理重复
prev_bd_name = None
prev_bd_email = None
for item in raw_data:
    row_content = []
    # 判断当前BD信息是否和上一行重复
    if item["BDName"] == prev_bd_name and item["BDEmail"] == prev_bd_email:
        row_content.extend(["", ""])
    else:
        row_content.extend([item["BDName"], item["BDEmail"]])
        prev_bd_name = item["BDName"]
        prev_bd_email = item["BDEmail"]
    # 添加其他字段
    row_content.extend([item["Process Id"], item["Customer Name"], item["Email"]])
    ws.append(row_content)

# 调整列宽适配内容
for col in ws.columns:
    max_len = 0
    col_letter = col[0].column_letter
    for cell in col:
        try:
            if len(str(cell.value)) > max_len:
                max_len = len(str(cell.value))
        except:
            pass
    ws.column_dimensions[col_letter].width = (max_len + 2) * 1.2

# 保存文件
wb.save("bd_report_simple.xlsx")

两种方法都能实现你要的效果:重复的BDName和BDEmail只在首次出现时显示,后续重复行的对应位置要么留空,要么合并成一个单元格。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:41:49