Python自动化办公实战:Excel数据处理与邮件自动发送系统 | Python高级应用

2025-09-09 0 924

前言:为什么需要办公自动化?

在日常办公中,我们经常需要处理大量的Excel数据并发送邮件报告。手动操作不仅耗时耗力,还容易出错。本教程将教你如何使用Python构建一个完整的自动化办公系统,实现Excel数据的自动处理和邮件发送功能。

项目概述与功能设计

我们将开发一个自动化系统,主要功能包括:

  • 读取和解析Excel数据文件
  • 数据清洗与转换
  • 生成数据可视化报告
  • 自动发送邮件附件
  • 错误处理与日志记录

环境准备与库安装

首先安装所需的Python库:

# 数据处理库
pip install pandas openpyxl xlrd

# 数据可视化库
pip install matplotlib seaborn

# 邮件发送库
pip install yagmail

# 日期处理库
pip install python-dateutil
        

核心代码实现

1. Excel数据读取与处理

使用Pandas库高效处理Excel数据:

import pandas as pd
import numpy as np
from datetime import datetime, timedelta

class ExcelProcessor:
    def __init__(self, file_path):
        self.file_path = file_path
        self.df = None
    
    def load_data(self):
        """加载Excel数据"""
        try:
            self.df = pd.read_excel(self.file_path, sheet_name='SalesData')
            print(f"成功加载数据,共{len(self.df)}行记录")
            return True
        except Exception as e:
            print(f"数据加载失败: {str(e)}")
            return False
    
    def clean_data(self):
        """数据清洗"""
        # 删除空值
        self.df = self.df.dropna()
        
        # 转换日期格式
        self.df['Date'] = pd.to_datetime(self.df['Date'], errors='coerce')
        
        # 过滤无效数据
        self.df = self.df[self.df['Sales'] > 0]
        
        # 重置索引
        self.df = self.df.reset_index(drop=True)
        
        return self.df
    
    def calculate_metrics(self):
        """计算关键指标"""
        metrics = {
            'total_sales': self.df['Sales'].sum(),
            'average_sales': self.df['Sales'].mean(),
            'max_sales': self.df['Sales'].max(),
            'min_sales': self.df['Sales'].min(),
            'record_count': len(self.df)
        }
        
        return metrics
    
    def generate_report(self, output_path):
        """生成分析报告"""
        # 按产品分类汇总
        product_summary = self.df.groupby('Product')['Sales'].agg(['sum', 'count', 'mean']).round(2)
        
        # 按日期趋势分析
        daily_sales = self.df.groupby(self.df['Date'].dt.date)['Sales'].sum()
        
        # 保存处理后的数据
        with pd.ExcelWriter(output_path) as writer:
            self.df.to_excel(writer, sheet_name='ProcessedData', index=False)
            product_summary.to_excel(writer, sheet_name='ProductSummary')
            daily_sales.to_excel(writer, sheet_name='DailyTrend')
        
        print(f"报告已生成: {output_path}")
        return output_path
            

2. 数据可视化生成

使用Matplotlib创建专业的数据图表:

import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib.dates import DateFormatter

class DataVisualizer:
    def __init__(self, df):
        self.df = df
        plt.style.use('seaborn-v0_8')
    
    def create_sales_trend_chart(self, output_path):
        """创建销售趋势图"""
        fig, ax = plt.subplots(figsize=(12, 6))
        
        # 按日期分组计算销售额
        daily_data = self.df.groupby(self.df['Date'].dt.date)['Sales'].sum()
        
        ax.plot(daily_data.index, daily_data.values, 
                marker='o', linewidth=2, markersize=4)
        
        ax.set_title('每日销售趋势图', fontsize=16, fontweight='bold')
        ax.set_xlabel('日期', fontsize=12)
        ax.set_ylabel('销售额', fontsize=12)
        
        # 格式化日期显示
        date_format = DateFormatter("%m-%d")
        ax.xaxis.set_major_formatter(date_format)
        
        plt.xticks(rotation=45)
        plt.tight_layout()
        plt.savefig(output_path, dpi=300, bbox_inches='tight')
        plt.close()
        
        return output_path
    
    def create_product_pie_chart(self, output_path):
        """创建产品占比饼图"""
        product_sales = self.df.groupby('Product')['Sales'].sum()
        
        fig, ax = plt.subplots(figsize=(10, 8))
        wedges, texts, autotexts = ax.pie(
            product_sales.values, 
            labels=product_sales.index,
            autopct='%1.1f%%',
            startangle=90,
            colors=sns.color_palette('pastel')
        )
        
        ax.set_title('产品销售额占比', fontsize=16, fontweight='bold')
        plt.savefig(output_path, dpi=300, bbox_inches='tight')
        plt.close()
        
        return output_path
    
    def create_comparison_chart(self, output_path):
        """创建产品对比柱状图"""
        product_stats = self.df.groupby('Product')['Sales'].agg(['mean', 'std'])
        
        fig, ax = plt.subplots(figsize=(12, 6))
        x_pos = np.arange(len(product_stats))
        
        bars = ax.bar(x_pos, product_stats['mean'], 
                     yerr=product_stats['std'],
                     capsize=5, alpha=0.7,
                     color=sns.color_palette('Set2'))
        
        ax.set_xlabel('产品', fontsize=12)
        ax.set_ylabel('平均销售额', fontsize=12)
        ax.set_title('产品销售额对比', fontsize=16, fontweight='bold')
        ax.set_xticks(x_pos)
        ax.set_xticklabels(product_stats.index, rotation=45)
        
        # 添加数值标签
        for i, bar in enumerate(bars):
            height = bar.get_height()
            ax.text(bar.get_x() + bar.get_width()/2., height + 0.1,
                   f'{height:.2f}', ha='center', va='bottom')
        
        plt.tight_layout()
        plt.savefig(output_path, dpi=300, bbox_inches='tight')
        plt.close()
        
        return output_path
            

3. 邮件自动发送系统

使用yagmail库实现邮件自动发送:

import yagmail
import os
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

class EmailSender:
    def __init__(self, sender_email, sender_password):
        self.sender_email = sender_email
        self.yag = yagmail.SMTP(sender_email, sender_password)
    
    def send_report(self, recipient_email, subject, 
                   body_content, attachments=None):
        """发送报告邮件"""
        try:
            # 创建邮件内容
            contents = [
                body_content,
            ]
            
            # 添加附件
            if attachments:
                if isinstance(attachments, str):
                    contents.append(attachments)
                elif isinstance(attachments, list):
                    contents.extend(attachments)
            
            # 发送邮件
            self.yag.send(
                to=recipient_email,
                subject=subject,
                contents=contents
            )
            
            print(f"邮件成功发送至: {recipient_email}")
            return True
            
        except Exception as e:
            print(f"邮件发送失败: {str(e)}")
            return False
    
    def create_email_body(self, metrics):
        """创建邮件正文内容"""
        body = f"""
<h2>销售数据报告 - {datetime.now().strftime('%Y年%m月%d日')}</h2>

<h3>关键指标汇总:</h3>
<ul>
<li>总销售额: ¥{metrics['total_sales']:,.2f}</li>
<li>平均销售额: ¥{metrics['average_sales']:,.2f}</li>
<li>最高销售额: ¥{metrics['max_sales']:,.2f}</li>
<li>最低销售额: ¥{metrics['min_sales']:,.2f}</li>
<li>记录总数: {metrics['record_count']} 条</li>
</ul>

<h3>报告包含内容:</h3>
<ol>
<li>数据处理后的Excel文件</li>
<li>销售趋势分析图表</li>
<li>产品占比分析图表</li>
<li>产品对比分析图表</li>
</ol>

<p>此邮件由Python自动化系统自动生成,请勿直接回复。</p>
<p>生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</p>
"""
        return body
            

系统集成与自动化调度

将各个模块整合成完整的自动化系统:

import schedule
import time
import logging
from pathlib import Path

class AutomationSystem:
    def __init__(self, config):
        self.config = config
        self.setup_logging()
    
    def setup_logging(self):
        """设置日志记录"""
        logging.basicConfig(
            filename='automation.log',
            level=logging.INFO,
            format='%(asctime)s - %(levelname)s - %(message)s'
        )
    
    def run_daily_task(self):
        """每日自动任务"""
        try:
            logging.info("开始执行每日自动化任务")
            
            # 1. 处理Excel数据
            processor = ExcelProcessor(self.config['excel_path'])
            if processor.load_data():
                processor.clean_data()
                metrics = processor.calculate_metrics()
                
                # 2. 生成报告文件
                report_path = processor.generate_report(
                    self.config['output_excel_path']
                )
                
                # 3. 创建可视化图表
                visualizer = DataVisualizer(processor.df)
                chart1 = visualizer.create_sales_trend_chart(
                    self.config['trend_chart_path']
                )
                chart2 = visualizer.create_product_pie_chart(
                    self.config['pie_chart_path']
                )
                chart3 = visualizer.create_comparison_chart(
                    self.config['comparison_chart_path']
                )
                
                # 4. 发送邮件
                email_sender = EmailSender(
                    self.config['email']['sender'],
                    self.config['email']['password']
                )
                
                body = email_sender.create_email_body(metrics)
                attachments = [
                    report_path,
                    chart1,
                    chart2,
                    chart3
                ]
                
                email_sender.send_report(
                    self.config['email']['recipient'],
                    f"每日销售报告 - {datetime.now().strftime('%Y-%m-%d')}",
                    body,
                    attachments
                )
                
                logging.info("每日自动化任务执行成功")
                
        except Exception as e:
            logging.error(f"任务执行失败: {str(e)}")
            # 可以添加错误通知机制
    
    def schedule_tasks(self):
        """安排定时任务"""
        # 每天上午9点执行
        schedule.every().day.at("09:00").do(self.run_daily_task)
        
        logging.info("自动化任务调度已启动")
        
        while True:
            schedule.run_pending()
            time.sleep(60)  # 每分钟检查一次

# 配置参数
config = {
    'excel_path': 'data/sales_data.xlsx',
    'output_excel_path': 'reports/processed_sales.xlsx',
    'trend_chart_path': 'charts/sales_trend.png',
    'pie_chart_path': 'charts/product_pie.png',
    'comparison_chart_path': 'charts/product_comparison.png',
    'email': {
        'sender': 'your_email@example.com',
        'password': 'your_app_password',  # 使用应用专用密码
        'recipient': 'recipient@example.com'
    }
}

# 启动系统
if __name__ == "__main__":
    system = AutomationSystem(config)
    system.run_daily_task()  # 立即执行一次
    # system.schedule_tasks()  # 或者启动定时任务
        

错误处理与日志管理

完善的错误处理机制确保系统稳定运行:

class ErrorHandler:
    @staticmethod
    def handle_file_error(func):
        """处理文件操作错误"""
        def wrapper(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except FileNotFoundError as e:
                logging.error(f"文件未找到: {str(e)}")
                raise
            except PermissionError as e:
                logging.error(f"权限错误: {str(e)}")
                raise
            except Exception as e:
                logging.error(f"文件操作错误: {str(e)}")
                raise
        return wrapper
    
    @staticmethod
    def handle_email_error(func):
        """处理邮件发送错误"""
        def wrapper(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except yagmail.SMTPAuthenticationError as e:
                logging.error(f"邮件认证失败: {str(e)}")
                # 发送警报通知
                raise
            except Exception as e:
                logging.error(f"邮件发送错误: {str(e)}")
                raise
        return wrapper
    
    @staticmethod
    def send_error_notification(error_message):
        """发送错误通知"""
        # 可以实现邮件、短信或其他方式的通知
        print(f"错误警报: {error_message}")
        

部署与优化建议

  • Windows任务计划:使用Windows任务计划程序定时运行脚本
  • Linux Cron作业:在Linux系统上使用crontab设置定时任务
  • Docker容器化:将应用打包为Docker容器便于部署
  • 性能优化:对于大数据集,考虑使用Dask替代Pandas
  • 安全考虑:妥善保管邮箱密码和敏感数据

总结与扩展

通过本教程,我们构建了一个完整的Python自动化办公系统,涵盖了数据处理、可视化、邮件发送等核心功能。这个系统可以进一步扩展:

  • 添加数据库支持,存储历史数据
  • 集成更多数据源(API、数据库等)
  • 添加Web界面进行配置和管理
  • 实现更复杂的业务逻辑和分析功能

Python办公自动化可以显著提高工作效率,减少人工错误,是现代职场中非常有价值的技能。

Python自动化办公实战:Excel数据处理与邮件自动发送系统 | Python高级应用
收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

淘吗网 python Python自动化办公实战:Excel数据处理与邮件自动发送系统 | Python高级应用 https://www.taomawang.com/server/python/1049.html

常见问题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务