最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python實(shí)現(xiàn)Excel批量處理+郵件自動(dòng)發(fā)送的全流程

 更新時(shí)間:2025年12月17日 08:36:19   作者:派大鑫wink  
在日常辦公中,重復(fù)的 Excel 數(shù)據(jù)整理、報(bào)表生成與郵件分發(fā)工作占據(jù)大量時(shí)間,本文將手把手教你用 Python 實(shí)現(xiàn) Excel 數(shù)據(jù)批量處理 + 自動(dòng)化郵件發(fā)送全流程,需要的朋友可以參考下

在日常辦公中,重復(fù)的 Excel 數(shù)據(jù)整理、報(bào)表生成與郵件分發(fā)工作占據(jù)大量時(shí)間。本文將手把手教你用 Python 實(shí)現(xiàn) “Excel 數(shù)據(jù)批量處理 + 自動(dòng)化郵件發(fā)送” 全流程,涵蓋數(shù)據(jù)讀取、清洗、格式美化、報(bào)表生成及郵件帶附件發(fā)送,支持自定義模板與批量操作,大幅提升辦公效率,適合行政、運(yùn)營、財(cái)務(wù)等崗位人員學(xué)習(xí)使用。

一、項(xiàng)目整體介紹

1.1 項(xiàng)目背景與價(jià)值

無論是月度業(yè)績報(bào)表分發(fā)、客戶數(shù)據(jù)統(tǒng)計(jì)通知,還是員工薪資條發(fā)放,都需要先整理 Excel 數(shù)據(jù),再手動(dòng)復(fù)制粘貼到郵件中發(fā)送 —— 過程繁瑣且易出錯(cuò)。本項(xiàng)目通過 Python 自動(dòng)化完成以下工作:

  • 批量讀取 Excel 數(shù)據(jù)(支持多工作表 / 多文件);
  • 數(shù)據(jù)清洗(缺失值填充、格式統(tǒng)一、重復(fù)數(shù)據(jù)剔除);
  • Excel 報(bào)表美化(單元格樣式、條件格式、圖表生成);
  • 自動(dòng)生成個(gè)性化郵件內(nèi)容(按收件人匹配對(duì)應(yīng)數(shù)據(jù));
  • 批量發(fā)送帶 Excel 附件的郵件,支持抄送 / 密送。

1.2 技術(shù)棧選型

技術(shù)模塊核心技術(shù)作用說明
Excel 處理openpyxl + pandas讀取 / 寫入 Excel 文件、數(shù)據(jù)清洗、格式美化、圖表生成(支持.xlsx 格式)
郵件發(fā)送smtplib + email連接 SMTP 服務(wù)器、構(gòu)造郵件內(nèi)容(文本 / HTML)、添加附件、批量發(fā)送
輔助工具os + datetime + logging文件路徑處理、時(shí)間格式轉(zhuǎn)換、操作日志記錄(便于問題排查)

1.3 核心功能模塊

系統(tǒng)采用 “模塊化設(shè)計(jì)”,可按需組合使用,核心功能如下:

  1. Excel 數(shù)據(jù)處理模塊
    • 多文件 / 多工作表批量讀?。?/li>
    • 數(shù)據(jù)清洗(缺失值填充、重復(fù)項(xiàng)刪除、數(shù)據(jù)格式轉(zhuǎn)換);
    • 報(bào)表美化(表頭樣式、數(shù)據(jù)對(duì)齊、條件格式高亮);
    • 自動(dòng)生成數(shù)據(jù)統(tǒng)計(jì)圖表(柱狀圖 / 餅圖)。
  2. 郵件發(fā)送模塊
    • 支持 QQ 郵箱、企業(yè)郵箱 SMTP 配置;
    • 自定義郵件主題、正文模板(支持變量替換,如 “XXX 先生 / 女士,您的月度業(yè)績?nèi)缦?rdquo;);
    • 自動(dòng)添加 Excel 附件(單個(gè) / 多個(gè));
    • 批量發(fā)送 + 失敗重試機(jī)制,日志記錄發(fā)送結(jié)果。

二、環(huán)境搭建與準(zhǔn)備

2.1 開發(fā)環(huán)境配置

  1. 基礎(chǔ)環(huán)境:Python 3.8+(推薦 3.9 版本,兼容性更佳);
  2. 依賴庫安裝:
# 核心依賴庫
pip install pandas openpyxl  # Excel讀取/寫入/美化
pip install python-dotenv    # 環(huán)境變量管理(存儲(chǔ)郵箱密碼等敏感信息)
pip install logging          # 日志記錄
  1. 郵箱 SMTP 配置(關(guān)鍵步驟):
    • 以 QQ 郵箱為例:登錄 QQ 郵箱 → Settings → 賬戶 → 開啟 “POP3/SMTP 服務(wù)” → 生成授權(quán)碼(替代密碼登錄);
    • 企業(yè)郵箱(如網(wǎng)易企業(yè)郵):開啟 SMTP 服務(wù),確認(rèn)服務(wù)器地址(如smtp.ym.163.com)與端口(通常 465,SSL 加密)。

2.2 項(xiàng)目目錄結(jié)構(gòu)

auto_office_system/
├── main.py                # 項(xiàng)目入口文件(整合Excel處理與郵件發(fā)送)
├── .env                   # 環(huán)境變量配置(郵箱賬號(hào)、授權(quán)碼、SMTP服務(wù)器)
├── excel_processor.py     # Excel數(shù)據(jù)處理模塊(讀取/清洗/美化/圖表)
├── email_sender.py        # 郵件發(fā)送模塊(SMTP連接/郵件構(gòu)造/批量發(fā)送)
├── templates/             # 模板文件
│   ├── email_template.html  # 郵件正文HTML模板
│   └── excel_template.xlsx  # Excel報(bào)表模板(可選)
├── input/                 # 輸入文件目錄(待處理的Excel文件)
│   └── 客戶數(shù)據(jù).xlsx
├── output/                # 輸出文件目錄(處理后的Excel報(bào)表)
└── logs/                  # 日志文件目錄(記錄操作過程與發(fā)送結(jié)果)

2.3 環(huán)境變量配置(.env 文件)

# 郵箱配置
SMTP_SERVER=smtp.qq.com    # SMTP服務(wù)器地址(QQ郵箱:smtp.qq.com;企業(yè)郵:如smtp.ym.163.com)
SMTP_PORT=465              # SMTP端口(SSL加密通常為465)
EMAIL_ACCOUNT=your_email@qq.com  # 發(fā)件人郵箱
EMAIL_PASSWORD=your_auth_code    # 郵箱授權(quán)碼(非登錄密碼)
 
# 郵件默認(rèn)配置
DEFAULT_CC=cc_email@qq.com  # 默認(rèn)抄送郵箱(可選)
DEFAULT_SUBJECT=【月度報(bào)表】客戶數(shù)據(jù)統(tǒng)計(jì)通知  # 默認(rèn)郵件主題

三、核心模塊實(shí)現(xiàn)

3.1 Excel 數(shù)據(jù)處理模塊(excel_processor.py)

實(shí)現(xiàn) Excel 數(shù)據(jù)的讀取、清洗、美化與圖表生成,支持多文件批量處理。

import pandas as pd
from openpyxl import load_workbook
from openpyxl.styles import Font, PatternFill, Border, Side, Alignment
from openpyxl.chart import BarChart, Reference
from openpyxl.chart.series import DataPoint
import os
from datetime import datetime

class ExcelProcessor:
    def __init__(self, input_dir="input", output_dir="output"):
        self.input_dir = input_dir  # 輸入文件目錄
        self.output_dir = output_dir  # 輸出文件目錄
        # 創(chuàng)建輸出目錄(不存在則創(chuàng)建)
        if not os.path.exists(output_dir):
            os.makedirs(output_dir)
    
    def read_excel_files(self):
        """批量讀取input目錄下所有Excel文件(支持.xlsx)"""
        excel_files = [f for f in os.listdir(self.input_dir) if f.endswith(".xlsx")]
        if not excel_files:
            raise FileNotFoundError("input目錄下未找到Excel文件(.xlsx格式)")
        
        all_data = []
        for file in excel_files:
            file_path = os.path.join(self.input_dir, file)
            # 讀取所有工作表
            xls = pd.ExcelFile(file_path)
            for sheet_name in xls.sheet_names:
                df = pd.read_excel(file_path, sheet_name=sheet_name)
                df["來源文件"] = file  # 新增列標(biāo)記數(shù)據(jù)來源
                df["來源工作表"] = sheet_name  # 新增列標(biāo)記工作表
                all_data.append(df)
        
        # 合并所有數(shù)據(jù)
        combined_df = pd.concat(all_data, ignore_index=True)
        print(f"成功讀取{len(excel_files)}個(gè)Excel文件,共{len(combined_df)}條數(shù)據(jù)")
        return combined_df
    
    def clean_data(self, df):
        """數(shù)據(jù)清洗:處理缺失值、重復(fù)項(xiàng)、格式統(tǒng)一"""
        # 1. 刪除完全重復(fù)的行
        df_clean = df.drop_duplicates()
        # 2. 填充缺失值(數(shù)值列填0,文本列填"未知")
        for col in df_clean.columns:
            if df_clean[col].dtype in ["int64", "float64"]:
                df_clean[col] = df_clean[col].fillna(0)
            else:
                df_clean[col] = df_clean[col].fillna("未知")
        # 3. 統(tǒng)一日期格式(若存在"日期"列)
        if "日期" in df_clean.columns:
            df_clean["日期"] = pd.to_datetime(df_clean["日期"], errors="coerce").dt.strftime("%Y-%m-%d")
        # 4. 去除字符串前后空格
        for col in df_clean.select_dtypes(include=["object"]).columns:
            df_clean[col] = df_clean[col].astype(str).str.strip()
        
        print(f"數(shù)據(jù)清洗完成:原始{len(df)}條 → 清洗后{len(df_clean)}條")
        return df_clean
    
    def beautify_excel(self, df, output_filename="processed_report.xlsx"):
        """Excel報(bào)表美化:設(shè)置樣式、條件格式、添加圖表"""
        output_path = os.path.join(self.output_dir, output_filename)
        
        # 保存DataFrame到Excel
        df.to_excel(output_path, index=False, sheet_name="清洗后數(shù)據(jù)")
        
        # 加載工作簿進(jìn)行樣式美化
        wb = load_workbook(output_path)
        ws = wb["清洗后數(shù)據(jù)"]
        
        # 1. 設(shè)置表頭樣式(藍(lán)色背景、白色字體、加粗、居中)
        header_font = Font(color="FFFFFF", bold=True)
        header_fill = PatternFill(start_color="4472C4", end_color="4472C4", fill_type="solid")
        header_alignment = Alignment(horizontal="center", vertical="center")
        # 邊框樣式
        thin_border = Border(
            left=Side(style="thin"), right=Side(style="thin"),
            top=Side(style="thin"), bottom=Side(style="thin")
        )
        
        # 應(yīng)用表頭樣式
        for col in range(1, ws.max_column + 1):
            cell = ws.cell(row=1, column=col)
            cell.font = header_font
            cell.fill = header_fill
            cell.alignment = header_alignment
            cell.border = thin_border
        
        # 2. 應(yīng)用數(shù)據(jù)區(qū)樣式(居中、邊框)
        for row in range(2, ws.max_row + 1):
            for col in range(1, ws.max_column + 1):
                cell = ws.cell(row=row, column=col)
                cell.alignment = Alignment(horizontal="center", vertical="center")
                cell.border = thin_border
        
        # 3. 自動(dòng)調(diào)整列寬
        for col in ws.columns:
            max_length = 0
            column = col[0].column_letter  # 獲取列字母(如A、B)
            for cell in col:
                try:
                    if len(str(cell.value)) > max_length:
                        max_length = len(str(cell.value))
                except:
                    pass
            adjusted_width = min(max_length + 2, 20)  # 最大寬度限制為20
            ws.column_dimensions[column].width = adjusted_width
        
        # 4. 添加數(shù)據(jù)統(tǒng)計(jì)圖表(以"客戶類型"和"成交金額"為例)
        if "客戶類型" in df.columns and "成交金額" in df.columns:
            # 統(tǒng)計(jì)各客戶類型成交金額
            chart_data = df.groupby("客戶類型")["成交金額"].sum().reset_index()
            
            # 創(chuàng)建柱狀圖
            chart = BarChart()
            chart.title = "各客戶類型成交金額統(tǒng)計(jì)"
            chart.x_axis.title = "客戶類型"
            chart.y_axis.title = "成交金額(元)"
            
            # 準(zhǔn)備圖表數(shù)據(jù)
            x_data = Reference(ws, min_col=chart_data.columns.get_loc("客戶類型") + 1, 
                              min_row=2, max_row=len(chart_data) + 1)
            y_data = Reference(ws, min_col=chart_data.columns.get_loc("成交金額") + 1, 
                              min_row=2, max_row=len(chart_data) + 1)
            
            # 添加數(shù)據(jù)系列
            series = chart.add_data(y_data, titles_from_data=False)
            chart.set_categories(x_data)
            
            # 設(shè)置圖表樣式(高亮最大值)
            max_val = chart_data["成交金額"].max()
            for i, val in enumerate(chart_data["成交金額"]):
                if val == max_val:
                    dp = DataPoint(idx=i, fill=PatternFill(start_color="FF0000", end_color="FF0000", fill_type="solid"))
                    series.dPt.append(dp)
            
            # 在新工作表插入圖表
            chart_ws = wb.create_sheet("數(shù)據(jù)統(tǒng)計(jì)圖表")
            chart_ws.add_chart(chart, "B2")
        
        # 保存美化后的Excel
        wb.save(output_path)
        print(f"Excel報(bào)表美化完成,保存路徑:{output_path}")
        return output_path
    
    def batch_process(self):
        """批量處理流程:讀取→清洗→美化"""
        try:
            # 1. 讀取數(shù)據(jù)
            raw_df = self.read_excel_files()
            # 2. 數(shù)據(jù)清洗
            clean_df = self.clean_data(raw_df)
            # 3. 報(bào)表美化(輸出文件名包含當(dāng)前日期)
            output_filename = f"客戶數(shù)據(jù)報(bào)表_{datetime.now().strftime('%Y%m%d')}.xlsx"
            output_path = self.beautify_excel(clean_df, output_filename)
            return output_path
        except Exception as e:
            print(f"Excel處理失?。簕str(e)}")
            raise

3.2 郵件發(fā)送模塊(email_sender.py)

實(shí)現(xiàn) SMTP 連接、郵件構(gòu)造、批量發(fā)送,支持 HTML 模板與 Excel 附件。

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
from dotenv import load_dotenv
import os
import logging
from datetime import datetime

# 加載環(huán)境變量
load_dotenv()

# 配置日志
logging.basicConfig(
    filename=f"logs/email_send_{datetime.now().strftime('%Y%m%d')}.log",
    level=logging.INFO,
    format="%(asctime)s - %(levelname)s - %(message)s"
)

class EmailSender:
    def __init__(self):
        # 從環(huán)境變量獲取郵箱配置
        self.smtp_server = os.getenv("SMTP_SERVER")
        self.smtp_port = int(os.getenv("SMTP_PORT", 465))
        self.email_account = os.getenv("EMAIL_ACCOUNT")
        self.email_password = os.getenv("EMAIL_PASSWORD")
        self.default_cc = os.getenv("DEFAULT_CC", "")
        self.default_subject = os.getenv("DEFAULT_SUBJECT", "自動(dòng)化郵件通知")
        
        # 驗(yàn)證配置
        self._validate_config()
    
    def _validate_config(self):
        """驗(yàn)證郵箱配置是否完整"""
        required_configs = ["SMTP_SERVER", "EMAIL_ACCOUNT", "EMAIL_PASSWORD"]
        for config in required_configs:
            if not os.getenv(config):
                raise ValueError(f".env文件中缺少配置:{config}")
    
    def _create_email(self, to_email, subject, content, attachments=None):
        """構(gòu)造郵件內(nèi)容(支持HTML正文、多個(gè)附件)"""
        # 創(chuàng)建郵件對(duì)象(帶附件)
        msg = MIMEMultipart()
        msg["From"] = Header(self.email_account, "utf-8")  # 發(fā)件人
        msg["To"] = Header(to_email, "utf-8")  # 收件人
        msg["Subject"] = Header(subject, "utf-8")  # 郵件主題
        
        # 添加抄送(若有)
        if self.default_cc:
            msg["Cc"] = Header(self.default_cc, "utf-8")
        
        # 添加HTML正文
        msg.attach(MIMEText(content, "html", "utf-8"))
        
        # 添加附件(支持多個(gè)文件)
        if attachments:
            attachments = attachments if isinstance(attachments, list) else [attachments]
            for file_path in attachments:
                if os.path.exists(file_path):
                    # 讀取文件內(nèi)容
                    with open(file_path, "rb") as f:
                        part = MIMEText(f.read(), "base64", "utf-8")
                        part["Content-Type"] = "application/octet-stream"
                        # 設(shè)置附件文件名
                        filename = os.path.basename(file_path)
                        part["Content-Disposition"] = f'attachment; filename="{filename}"'
                        msg.attach(part)
                    logging.info(f"添加附件成功:{filename}")
                else:
                    logging.warning(f"附件文件不存在:{file_path}")
        
        return msg
    
    def load_html_template(self, template_path="templates/email_template.html", **kwargs):
        """加載HTML郵件模板,替換變量(如{username}、{date})"""
        if not os.path.exists(template_path):
            raise FileNotFoundError(f"郵件模板文件不存在:{template_path}")
        
        with open(template_path, "r", encoding="utf-8") as f:
            html_content = f.read()
        
        # 替換模板變量(kwargs中的key對(duì)應(yīng)模板中的{key})
        for key, value in kwargs.items():
            html_content = html_content.replace(f"{{{key}}}", str(value))
        
        return html_content
    
    def send_email(self, to_email, subject=None, content=None, attachments=None, retry=2):
        """發(fā)送單封郵件,支持失敗重試"""
        subject = subject or self.default_subject
        if not content:
            # 使用默認(rèn)文本內(nèi)容(若未提供HTML模板)
            content = f"您好!這是一封自動(dòng)化郵件通知,附件為相關(guān)報(bào)表,請(qǐng)查收。\n發(fā)送時(shí)間:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
        
        # 構(gòu)造收件人列表(含抄送)
        recipients = [to_email]
        if self.default_cc:
            recipients.extend(self.default_cc.split(","))
        
        for attempt in range(retry + 1):
            try:
                # 連接SMTP服務(wù)器(SSL加密)
                with smtplib.SMTP_SSL(self.smtp_server, self.smtp_port) as server:
                    server.login(self.email_account, self.email_password)
                    # 構(gòu)造郵件
                    msg = self._create_email(to_email, subject, content, attachments)
                    # 發(fā)送郵件
                    server.sendmail(self.email_account, recipients, msg.as_string())
                logging.info(f"郵件發(fā)送成功:收件人={to_email},主題={subject}")
                return True
            except Exception as e:
                logging.error(f"第{attempt+1}次發(fā)送郵件失?。ㄊ占?{to_email}):{str(e)}")
                if attempt >= retry:
                    logging.error(f"郵件發(fā)送最終失?。菏占?{to_email}")
                    return False
        return False
    
    def batch_send_emails(self, email_data_list, attachments=None):
        """批量發(fā)送郵件:接收收件人數(shù)據(jù)列表,支持個(gè)性化內(nèi)容"""
        """
        email_data_list格式:
        [
            {"to_email": "user1@qq.com", "username": "張三", "month": "2024-05"},
            {"to_email": "user2@qq.com", "username": "李四", "month": "2024-05"}
        ]
        """
        if not email_data_list:
            logging.warning("批量發(fā)送:未提供收件人數(shù)據(jù)")
            return
        
        success_count = 0
        fail_count = 0
        fail_emails = []
        
        for data in email_data_list:
            to_email = data.get("to_email")
            if not to_email:
                logging.warning("跳過無效數(shù)據(jù):未包含收件人郵箱")
                continue
            
            try:
                # 加載HTML模板并替換變量
                content = self.load_html_template(
                    username=data.get("username", "用戶"),
                    month=data.get("month", datetime.now().strftime("%Y-%m")),
                    send_time=datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                )
                
                # 發(fā)送郵件
                result = self.send_email(
                    to_email=to_email,
                    subject=f"{self.default_subject}({data.get('month', '')})",
                    content=content,
                    attachments=attachments
                )
                
                if result:
                    success_count += 1
                else:
                    fail_count += 1
                    fail_emails.append(to_email)
            except Exception as e:
                logging.error(f"批量發(fā)送失敗(收件人={to_email}):{str(e)}")
                fail_count += 1
                fail_emails.append(to_email)
        
        # 打印批量發(fā)送統(tǒng)計(jì)
        total = len(email_data_list)
        print(f"\n批量發(fā)送完成:總計(jì){total}封 → 成功{success_count}封 → 失敗{fail_count}封")
        if fail_emails:
            print(f"發(fā)送失敗的郵箱:{', '.join(fail_emails)}")
            logging.info(f"批量發(fā)送統(tǒng)計(jì):總計(jì){total}封 → 成功{success_count}封 → 失敗{fail_count}封,失敗郵箱:{fail_emails}")
        
        return {
            "total": total,
            "success": success_count,
            "fail": fail_count,
            "fail_emails": fail_emails
        }

3.3 郵件 HTML 模板(templates/email_template.html)

支持個(gè)性化變量替換,樣式美觀,適合正式辦公場景。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>客戶數(shù)據(jù)統(tǒng)計(jì)通知</title>
    <style>
        body { font-family: "Microsoft YaHei", sans-serif; line-height: 1.6; color: #333; }
        .container { width: 80%; margin: 0 auto; padding: 20px; border: 1px solid #eee; border-radius: 8px; }
        .header { background-color: #4472C4; color: white; padding: 15px; border-radius: 8px 8px 0 0; text-align: center; }
        .content { padding: 20px; }
        .highlight { color: #4472C4; font-weight: bold; }
        .footer { margin-top: 30px; padding-top: 15px; border-top: 1px solid #eee; text-align: center; color: #666; }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h2>【月度客戶數(shù)據(jù)統(tǒng)計(jì)報(bào)表】</h2>
        </div>
        <div class="content">
            <p>尊敬的<span class="highlight">{username}</span>先生/女士:</p>
            <p>您好!現(xiàn)將{month}月度客戶數(shù)據(jù)統(tǒng)計(jì)報(bào)表發(fā)送給您,具體說明如下:</p>
            <ul>
                <li>報(bào)表包含客戶基本信息、成交金額、跟進(jìn)狀態(tài)等關(guān)鍵數(shù)據(jù);</li>
                <li>報(bào)表已按客戶類型分類統(tǒng)計(jì),并附數(shù)據(jù)可視化圖表;</li>
                <li>請(qǐng)您查收附件并核對(duì)數(shù)據(jù),如有疑問請(qǐng)及時(shí)反饋。</li>
            </ul>
            <p>發(fā)送時(shí)間:<span class="highlight">{send_time}</span></p>
            <p>祝您工作順利!</p>
        </div>
        <div class="footer">
            <p>本郵件為自動(dòng)化發(fā)送,請(qǐng)勿直接回復(fù) | 聯(lián)系電話:XXX-XXXXXXX</p>
        </div>
    </div>
</body>
</html>

3.4 項(xiàng)目入口文件(main.py)

整合 Excel 處理與郵件發(fā)送流程,支持命令行運(yùn)行。

from excel_processor import ExcelProcessor
from email_sender import EmailSender
import logging

# 配置日志
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")

def main():
    try:
        # 第一步:Excel數(shù)據(jù)批量處理(讀取→清洗→美化)
        logging.info("="*50)
        logging.info("開始Excel數(shù)據(jù)處理...")
        excel_processor = ExcelProcessor()
        excel_report_path = excel_processor.batch_process()
        logging.info(f"Excel處理完成,報(bào)表路徑:{excel_report_path}")
        
        # 第二步:批量發(fā)送郵件(示例數(shù)據(jù),實(shí)際可從Excel讀取收件人信息)
        logging.info("\n" + "="*50)
        logging.info("開始批量發(fā)送郵件...")
        email_sender = EmailSender()
        
        # 收件人數(shù)據(jù)列表(實(shí)際項(xiàng)目可從Excel讀?。喝鏿d.read_excel("收件人列表.xlsx"))
        email_data_list = [
            {"to_email": "recipient1@qq.com", "username": "張三", "month": "2024-05"},
            {"to_email": "recipient2@163.com", "username": "李四", "month": "2024-05"},
            {"to_email": "recipient3@ym.163.com", "username": "王五", "month": "2024-05"}
        ]
        
        # 批量發(fā)送郵件(添加Excel報(bào)表作為附件)
        send_result = email_sender.batch_send_emails(
            email_data_list=email_data_list,
            attachments=excel_report_path
        )
        
        # 輸出最終結(jié)果
        logging.info("\n" + "="*50)
        logging.info(f"自動(dòng)化流程全部完成!")
        logging.info(f"Excel報(bào)表:{excel_report_path}")
        logging.info(f"郵件發(fā)送統(tǒng)計(jì):成功{send_result['success']}封,失敗{send_result['fail']}封")
        
    except Exception as e:
        logging.error(f"自動(dòng)化流程執(zhí)行失敗:{str(e)}", exc_info=True)
        print(f"執(zhí)行失?。簕str(e)}")

if __name__ == "__main__":
    main()

四、系統(tǒng)運(yùn)行與效果展示

4.1 運(yùn)行步驟

  1. 準(zhǔn)備工作:在input目錄下放入待處理的 Excel 文件(如 “客戶數(shù)據(jù).xlsx”),確保包含 “客戶類型”“成交金額”“日期” 等關(guān)鍵列;
  2. 配置.env 文件:填寫發(fā)件人郵箱、授權(quán)碼、SMTP 服務(wù)器等信息;
  3. 運(yùn)行程序:python main.py;
  4. 查看結(jié)果:
    • 處理后的 Excel 報(bào)表保存在output目錄(含美化樣式與統(tǒng)計(jì)圖表);
    • 郵件發(fā)送結(jié)果記錄在logs目錄的日志文件中;
    • 收件人將收到帶 HTML 格式正文與 Excel 附件的郵件。

4.2 核心效果展示

1. Excel 報(bào)表美化效果

  • 表頭:藍(lán)色背景、白色加粗字體、居中對(duì)齊;
  • 數(shù)據(jù)區(qū):統(tǒng)一居中、添加邊框、自動(dòng)調(diào)整列寬;
  • 條件格式:統(tǒng)計(jì)圖表中高亮顯示成交金額最大值;
  • 額外工作表:包含客戶類型成交金額柱狀圖,直觀呈現(xiàn)數(shù)據(jù)趨勢。

2. 郵件接收效果

  • 正文:HTML 格式,包含個(gè)性化問候(如 “尊敬的張三先生 / 女士”)、月度信息、發(fā)送時(shí)間;
  • 附件:自動(dòng)添加處理后的 Excel 報(bào)表,支持在線預(yù)覽或下載;
  • 抄送:默認(rèn)抄送郵箱可收到相同郵件,便于存檔。

4.3 日志記錄效果

日志文件將詳細(xì)記錄每一步操作:

2024-05-20 14:30:00,123 - INFO - 開始Excel數(shù)據(jù)處理...
2024-05-20 14:30:02,456 - INFO - 成功讀取1個(gè)Excel文件,共100條數(shù)據(jù)
2024-05-20 14:30:02,789 - INFO - 數(shù)據(jù)清洗完成:原始100條 → 清洗后98條
2024-05-20 14:30:05,123 - INFO - Excel報(bào)表美化完成,保存路徑:output/客戶數(shù)據(jù)報(bào)表_20240520.xlsx
2024-05-20 14:30:05,123 - INFO - 開始批量發(fā)送郵件...
2024-05-20 14:30:08,456 - INFO - 郵件發(fā)送成功:收件人=recipient1@qq.com,主題=【月度報(bào)表】客戶數(shù)據(jù)統(tǒng)計(jì)通知(2024-05)
2024-05-20 14:30:10,789 - INFO - 郵件發(fā)送成功:收件人=recipient2@163.com,主題=【月度報(bào)表】客戶數(shù)據(jù)統(tǒng)計(jì)通知(2024-05)
2024-05-20 14:30:12,123 - ERROR - 第2次發(fā)送郵件失?。ㄊ占?recipient3@ym.163.com):SMTPConnectError
2024-05-20 14:30:12,123 - INFO - 批量發(fā)送完成:總計(jì)3封 → 成功2封 → 失敗1封
2024-05-20 14:30:12,123 - INFO - 自動(dòng)化流程全部完成!

五、項(xiàng)目拓展與優(yōu)化方向

功能拓展:

  • 支持讀取 CSV/CSV 文件,擴(kuò)大輸入格式范圍;
  • 實(shí)現(xiàn) Excel 數(shù)據(jù)篩選與拆分(如按部門 / 區(qū)域拆分報(bào)表,分別發(fā)送給對(duì)應(yīng)負(fù)責(zé)人);
  • 增加郵件發(fā)送狀態(tài)回執(zhí)(確認(rèn)收件人已讀);
  • 支持多附件發(fā)送(如同時(shí)發(fā)送 Excel 報(bào)表 + PDF 說明文檔)。

系統(tǒng)優(yōu)化:

  • 引入 Redis 緩存頻繁使用的數(shù)據(jù)(如收件人列表),提升效率;
  • 增加異常監(jiān)控(如郵件發(fā)送失敗后自動(dòng)發(fā)送告警通知給管理員);
  • 支持定時(shí)任務(wù)(使用 APScheduler),每月自動(dòng)執(zhí)行報(bào)表生成與郵件發(fā)送;
  • 優(yōu)化 Excel 處理性能,支持超大文件(10 萬行 + 數(shù)據(jù))批量處理。

交互優(yōu)化:

  • 開發(fā)簡單 GUI 界面(使用 tkinter/pyqt),無需編寫代碼即可操作;
  • 支持自定義郵件模板與 Excel 樣式模板,適配不同辦公場景;
  • 增加數(shù)據(jù)預(yù)覽功能,處理前可查看原始數(shù)據(jù)與清洗效果。

六、總結(jié)

本項(xiàng)目基于 Python 實(shí)現(xiàn)了 “Excel 批量處理 + 自動(dòng)化郵件發(fā)送” 的完整辦公流程,技術(shù)棧簡潔實(shí)用,代碼結(jié)構(gòu)清晰,可直接應(yīng)用于實(shí)際工作場景。通過本項(xiàng)目的學(xué)習(xí),你可以掌握:

  • pandas/openpyxl 的 Excel 數(shù)據(jù)處理與美化技巧;
  • smtplib/email 的郵件構(gòu)造與批量發(fā)送方法;
  • 模塊化編程與環(huán)境變量管理(敏感信息保護(hù));
  • 日志記錄與異常處理的工業(yè)級(jí)編程思維。

項(xiàng)目可根據(jù)實(shí)際辦公需求靈活拓展,例如財(cái)務(wù)薪資條發(fā)放、運(yùn)營業(yè)績報(bào)表分發(fā)、行政通知推送等場景。建議在使用過程中結(jié)合自身工作流程調(diào)整代碼,積累自動(dòng)化辦公經(jīng)驗(yàn),逐步實(shí)現(xiàn) “一鍵搞定重復(fù)工作” 的高效辦公模式。

以上就是Python實(shí)現(xiàn)Excel批量處理+郵件自動(dòng)發(fā)送的全流程的詳細(xì)內(nèi)容,更多關(guān)于Python Excel批量處理和郵件自動(dòng)發(fā)送的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論

定结县| 三亚市| 安塞县| 时尚| 大姚县| 沙田区| 瑞金市| 崇信县| 五寨县| 景谷| 温泉县| 德令哈市| 封丘县| 天峻县| 英德市| 苏尼特左旗| 台东县| 池州市| 平乐县| 南宁市| 温泉县| 文昌市| 石狮市| 溧阳市| 休宁县| 宜君县| 望谟县| 大连市| 绥德县| 牡丹江市| 赤城县| 三明市| 宜兰市| 华蓥市| 涿鹿县| 汾西县| 台江县| 浮山县| 平陆县| 博湖县| 连平县|