如何使用Python自动化数据导出并发送电子邮件报告 – 一步步指南

如何使用Python自动导出数据和发送电子邮件报告-一步一步指南

在今天数据驱动的世界中,自动化是简化任务和节省时间的关键。在这个适合初学者的教程中,我将带你逐步介绍如何使用Python自动从PostgreSQL数据库导出数据并将其作为附件发送到电子邮件。

这个分步指南将帮助你掌握与数据库、数据操作和电子邮件通信相关的基础知识,并通过Python脚本实现自动化。

商业背景

想象一下,你是一个组织中的一员,你的经理期望每周报告中充满有价值的见解。但是创建这个报告远非一项直截了当的任务。

为了获取所需的信息,你必须手动执行十个不同的数据库查询,收集结果,然后仔细地将它们编译成Excel电子表格。这是一个耗时且容易出错的过程,可能会让你筋疲力尽。

在这种情况下,如果Python代替你掌控整个过程,是否会是一个改变游戏规则的机会?

想象一下:每周都没有人为干预,Python无缝地提取所需数据,将其编译成整洁的Excel表格,甚至准时发送给你的经理。

本教程将帮助你学习如何做到这一点。我将引导你逐步完成自动化这个过程,让你的每周或每月报告轻松自如,让你有更多时间专注于更重要的任务。

目录

  1. 准备条件
  2. 如何设置你的虚拟环境
  3. 如何设置你的示例数据库
  4. 如何设置日志记录和环境变量
  5. 如何从数据库中提取数据
  6. 如何使用BookingInfo类结构化预订数据
  7. 如何将数据转换为Excel表格
  8. 如何合并功能
  9. 如何发送带有预订数据报告的电子邮件
  10. 如何测试流程
  11. 如何安排应用程序
  12. 总结

准备条件

在开始之前,请确保你具备以下条件:

  1. 在您的计算机上安装了Python。您可以从Python.org下载Python。
  2. 基本的Python编程语言知识
  3. 熟悉在Python中发送电子邮件
  4. 在您的计算机上安装了PostgreSQL。您可以从这里下载PostgreSQL。

如何设置你的虚拟环境

在编写代码之前,你需要确保你安装了所有必要的工具和库。

为了确保你拥有一个干净且隔离的环境,你将使用venv创建一个虚拟环境

创建一个项目目录并在终端中导航到该目录:

mkdir report-automationcd report-automation

使用以下命令创建一个名为env的虚拟环境:

python -m venv env

Python现在预装了venv库,用于创建虚拟环境。

像这样激活虚拟环境:

source env/bin/activate

注意:如果你使用的是Windows系统,你需要使用source env/Scripts/activate来激活环境。

你应该在终端提示符中看到(env),表示虚拟环境已被激活。

安装所需的库

现在你已经创建了虚拟环境,可以安装以下库:

  • psycopg2:Python适配器,用于使Python应用程序与PostgreSQL数据库进行交互。
  • pandas:一种多功能的用于Python的数据操作和分析库,非常适合处理结构化数据。
  • xlsxwriter:创建和格式化Excel(XLSX)文件的Python模块,对于生成报告和电子表格非常有用。

要安装这些库,运行以下命令:

pip install psycopg2 pandas xlsxwriter

如何设置示例数据库

在本节中,我将指导你设置一个名为”airlines”的演示数据库,我们将在整个教程中使用它。该数据库包含三个表:bookingsflightsairports_data

我将为你提供一个名为airlines_db.sql的SQL脚本文件,该文件将创建数据库并用示例数据填充。要设置数据库,你需要在系统上安装PostgreSQL。

下载并安装数据库

  1. 从这里下载SQL脚本文件”airlines_db.sql”。
  2. 打开你的终端或命令提示符。
  3. 使用以下命令安装数据库。确保你已经安装了PostgreSQL的命令行工具,且可以访问psql命令。如果你的PostgreSQL用户名不同,请将postgres替换为你的用户名。
psql -f airlines_db.sql -U postgres

这个命令将执行SQL脚本,并创建带有bookingsflightsairports_data表的”airlines”数据库。

模式说明

数据库中的主要模式是bookings。让我们更详细地看一下”airlines”数据库中的表:

Screenshot-2023-10-29-115228
模式图

bookings.bookings

“bookings”表用于存储有关预订航班的关键信息。每个预订通过book_ref唯一标识,book_ref是一个character(6)类型的字段。total_amount字段是一个numeric(10,2)类型,表示预订的总费用。

为了跟踪预订日期和时间,该表包括一个book_date字段,类型为bigint。该表用作预订数据的中央存储库,对于跟踪乘客预订、费用和预订日期至关重要。

bookings.flights

“flights”表专门用于捕获有关航班的详细信息,包括它们的状态、预计和实际的起飞和到达时间以及其他重要的与航班相关的数据。

该表的主键是flight_id,一个integer标识符。每个航班与特定的航班号相关联,航班号由flight_no字段表示,是一个character(6)类型的字段。

为了了解航班的起点和目的地,departure_airportarrival_airport字段以character(3)类型分别存储出发和到达机场代码。

status字段是一个character varying(20),记录航班的状态,必须是 ‘On Time’、’Delayed’、’Departed’、’Arrived’、’Scheduled’或’Cancelled’之一。该表还包括预定的出发和到达时间字段(scheduled_departurescheduled_arrival)以及实际的出发和到达时间字段(actual_departureactual_arrival)。

此外,此表建立了两个关键的外键:flights_arrival_airport_fkeyflights_departure_airport_fkey,它们与 “airports_data” 表中的 airport_code 相关联。这种关联连接了航班和它们相应的出发和到达机场。

表格 bookings.airports_data

“airports_data” 表格作为存放与机场和其地理位置相关数据的库。每个机场通过存储在 airport_code 字段中的唯一的 character(3) 代码进行标识,它也是主键。

timezone 字段是一个 text 类型,记录了机场的具体时区信息,为调度和运营目的提供了重要信息。airport_name 字段是一个 character varying 类型,保存了机场的名称。此外,表格还包括 city 字段作为一个 character varying 类型,表示机场所处的城市。

这些详细信息使得 “airports_data” 表格能够提供机场位置和信息的全面概述。通过 flights_arrival_airport_fkeyflights_departure_airport_fkey 外键,它为 “flights” 表格提供了参考,促进了航班与相应的出发和到达机场之间的关联。

如何设置日志和环境变量

在本节中,我们将配置日志记录以提供有用的消息,并处理代码中的错误。我们还将设置环境变量以安全存储敏感信息和配置参数。这些实践增强了代码的可读性、可维护性和安全性。

日志配置

我们将利用Python内置的logging模块来配置日志系统。日志对于跟踪代码的执行流程和捕获重要信息或错误至关重要。

调用logging.basicConfig方法来定义日志消息的格式,并将日志级别设置为INFO

import logginglogging.basicConfig(    format="%(asctime)s | %(levelname)s : %(message)s", level=logging.INFO)
  • 格式format参数指定日志消息的格式。在这种情况下,每个日志条目包括时间戳、日志级别(例如,INFO、ERROR)和实际的日志消息。
  • 日志级别:我们将日志级别设置为INFO,这意味着记录信息性的消息。您还可以使用更高的严重级别,如WARNINGERROR,处理更严重的问题。

您可以在此教程中了解有关Python日志记录的更多信息。

如何管理环境变量

我们将创建一个.env文件来管理环境变量。环境变量用于存储敏感信息和配置设置,使我们能够将此类数据与代码分离。

在此示例中,我们为电子邮件凭据和数据库连接详细信息设置环境变量。

export EMAIL=export PASSWORD=export EMAIL_PORT=587export SMTP_SERVER=smtp.gmail.comexport DB_HOSTNAME=localhostexport DB_NAME=airlinesexport DB_PORT=5432export DB_USERNAME=postgresexport DB_PASSWORD=postgres

以下是这些变量的说明:

  • EMAIL:用于发送电子邮件的电子邮件地址。
  • PASSWORD:与电子邮件帐户关联的密码。
  • EMAIL_PORT:用于电子邮件服务器(例如SMTP服务器)的端口。默认端口为587,用于安全的电子邮件传输(TLS/SSL)。
  • SMTP_SERVER:SMTP服务器地址,通常特定于电子邮件服务提供商。
  • DB_HOSTNAME:PostgreSQL数据库服务器的主机名或IP地址。
  • DB_NAME:PostgreSQL数据库的名称。
  • DB_PORT:用于连接数据库的端口号(PostgreSQL的默认端口为5432)。
  • DB_USERNAME:用于与数据库进行身份验证的用户名。
  • DB_PASSWORD:数据库用户的密码。

请确保运行source .env来加载环境变量。

通过使用环境变量,可以将敏感数据(如密码和电子邮件凭据)与代码分开,减少意外曝光或未经授权访问的风险。代码可以在运行时访问这些变量,确保安全性和灵活的配置。

如何从数据库中提取数据

让我们从设置数据库配置开始。

import loggingimport oslogging.basicConfig(    format="%(asctime)s | %(levelname)s : %(message)s", level=logging.INFO)DB_CONFIG = {    "host": os.environ.get("DB_HOSTNAME"),    "database": os.environ.get("DB_NAME"),    "user": os.environ.get("DB_USERNAME"),    "password": os.environ.get("DB_PASSWORD"),}

DB_CONFIG字典用于存储连接到 PostgreSQL 数据库的配置参数。这些参数包括主机、数据库名称、用户名和密码。这些值可以通过环境变量设置。

如何连接到数据库

在从数据库中提取数据之前,我们需要连接到数据库。我们将使用psycopg2库来连接到 PostgreSQL 数据库。

我们将首先定义一个DataExporter类,该类将包含从数据库中提取数据和生成 Excel 表格的方法。

class DataExporter:    def __init__(self):        """使用数据库配置初始化 DataExporter。"""        self.db_config = DB_CONFIG

类构造函数使用存储在DB_CONFIG字典中的数据库配置来初始化DataExporter

接下来,让我们定义一个连接到数据库的方法。

...import psycopg2...class DataExporter:    def __init__(self):        """使用数据库配置初始化 DataExporter。"""        self.db_config = DB_CONFIG    def __connect_to_database(self) -> None:        """        建立与 PostgreSQL 数据库的连接。        Raises:            Exception: 如果无法连接到数据库。        """        try:            self.conn = psycopg2.connect(**self.db_config)            self.cursor = self.conn.cursor()            logging.info("已连接到数据库")        except Exception as e:            logging.error(                "无法连接到数据库,错误:%s", e)            raise

__connect_to_database私有方法负责建立与 PostgreSQL 数据库的连接。它使用psycopg2库创建连接和用于执行 SQL 查询的游标。如果连接失败,它会记录一个错误并引发异常。

你可以在此处了解更多有关 Python 异常处理的信息。

如何从数据库获取数据

现在,我们将定义另一个私有方法,该方法连接到数据库并从数据库中提取预订总数和总金额。

from datetime import datetimeclass DataExporter:    ...    def __fetch_from_database(self, start_timestamp, end_timestamp) -> list | None:        """        根据给定的时间范围从数据库中提取预订数据。        Args:            start_timestamp (datetime): 时间范围的开始。            end_timestamp (datetime): 时间范围的结束。        Returns:            list: 包含预订数据(num_bookings, total_amount)的列表,如果发生错误则返回 None。        """        self.__connect_to_database()        query = f"""        SELECT COUNT(*) AS num_bookings, SUM(total_amount) AS total_amount        FROM bookings        WHERE book_date >= {int(start_timestamp.timestamp()) * 1000} AND book_date <= {int(end_timestamp.timestamp()) * 1000}        """        logging.info(            "从数据库中提取预订数据,开始时间戳:%s,结束时间戳:%s",            start_timestamp,            end_timestamp,        )        result = None        try:            self.cursor.execute(query)            result = list(self.cursor.fetchone())            result.append(                f'{start_timestamp.strftime("%d %b, %Y")} - {end_timestamp.strftime("%d %b, %Y")}'            )            logging.info(                "成功从数据库中提取预订数据,开始时间戳:%s,结束时间戳:%s",                start_timestamp,                end_timestamp,            )        except Exception as e:            logging.error(                "从数据库中提取预订数据出错:%s", e            )        return result

这个私有方法从数据库中检索指定时间范围的预订数据。

它以两个datetime对象作为参数,即start_timestampend_timestamp。它还构建一个SQL查询来检索该时间范围内的预订数量和总预订金额。

查询被执行,如果成功,则该方法将数据作为元组返回。我们将元组转换为列表,并将提取数据的时间范围附加到列表中。如果在与数据库的交互过程中发生错误,则记录错误并返回None

使用上述方法,您可以提取各种时间范围的预订数据,无论是一周、一个月、一年还是您选择的任何自定义时间范围。

如何使用BookingInfo类组织预订数据

在本节中,我们将在booking_info.py中定义一个BookingInfo类,它作为从数据库中检索的预订数据的结构化容器。该类封装了与预订相关的信息,使得使用和呈现数据更加容易。

from decimal import Decimalclass BookingInfo:    def __init__(self, data_list: list):        """        用数据库的数据初始化BookingInfo。        参数:            data_list(list):包含预订数据(total_bookings,total_amount,timestamp)的列表。        注意:            total_amount将转换为Decimal类型。        """        self.__total_bookings, self.__total_amount, self.__timestamp = data_list        self.__total_amount = Decimal(self.__total_amount) if self.__total_amount else Decimal(0)    def __str__(self) -> str:        """        返回BookingInfo的字符串表示形式。        返回:            str:格式为"Total Bookings: X, Total Amount: $Y"的字符串。        """        return f"Total Bookings: {self.__total_bookings}, Total Amount: ${self.__total_amount}"    def get_total_bookings(self) -> int:        """        获取预订总数。        返回:            int:预订总数。        """        return self.__total_bookings    def get_total_amount(self) -> Decimal:        """        获取预订总金额(以Decimal类型返回)。        返回:            Decimal:预订总金额。        """        return self.__total_amount    def get_timestamp(self) -> str:        """        获取与预订数据关联的时间戳。        返回:            str:作为字符串的时间戳。        """        return self.__timestamp

BookingInfo类旨在组织和表示从数据库返回的预订数据。它接收一个值列表作为输入,该列表包含总预订数、总预订金额和时间戳,并将总金额转换为Decimal类型。该类提供了访问和以结构化方式呈现此数据的方法。

BookingInfo类的构造方法接受data_list作为输入,该输入应为包含以下元素的列表:

  • total_bookings:表示预订总数的整数。
  • total_amount:表示总预订金额的浮点数。
  • timestamp:与预订数据相关联的时间戳。

__init__方法使用data_list中的值初始化私有实例变量(__total_bookings__total_amount__timestamp)。它还将__total_amount转换为十进制类型以精确处理货币值。

__str__方法用于提供BookingInfo对象的字符串表示形式。它返回一个字符串,格式为”Total Bookings: X, Total Amount: $Y”,其中X是预订总数,Y是以美元格式化的总预订金额。

Getter方法

该类提供了三个getter方法来访问封装的数据:

  • get_total_bookings():以整数形式返回预订总数。
  • get_total_amount():以Decimal类型返回总预订金额。
  • get_timestamp():以字符串形式返回与预订数据关联的时间戳。

通过将预订数据封装在BookingInfo类中,代码更有条理,可读性更强,可重用性更高。这种结构化的方法简化了应用程序中预订信息的处理,使其更易于使用和展示数据。

如何将数据转换为Excel表格

现在您可以从数据库中检索特定时间范围的数据,还可以基于提取的数据生成Excel表格。

为此,让我们定义另一个私有方法来创建Excel表格。

...import pandas as pdfrom booking_info import BookingInfo...class DataExporter:	...    def __convert_to_excelsheet(self, data: list, sheet_name: str):        """将提取的数据转换为Excel表格。            第一个参数data (list): 包含预订数据的列表。            第二个参数sheet_name (str): 要创建的Excel表格的名称。            Raises:                ValueError: 如果转换数据为Excel表格时发生错误。        """        try:            booking_info = BookingInfo(data)            data = {                "": ["总预订量", "总金额(美元)"],                booking_info.get_timestamp(): [                    booking_info.get_total_bookings(),                    booking_info.get_total_amount(),                ],            }            logging.info("将数据转换为pandas dataframe")            df = pd.DataFrame(data)            logging.info("将数据插入到Excel表格中")            with pd.ExcelWriter(sheet_name, engine="xlsxwriter") as writer:                df.to_excel(writer, sheet_name="Sheet1", index=False)            logging.info("成功将数据插入到Excel表格中")        except ValueError as e:            logging.error("将数据转换为Excel时出错:%s", e)

DataExporter类中的__convert_to_excelsheet方法负责将提取的预订数据结构化并转换为Excel表格。

该方法接受两个输入参数。第一个参数data应为包含特定预订数据的列表。该数据包括预订总数、预订总金额和提取数据的时间戳。第二个参数sheet_name表示所需的包含格式化数据的Excel表格的名称。

该方法的一个关键方面是数据的结构化。为实现这一点,方法创建一个名为booking_infoBookingInfo对象。该BookingInfo对象提供了预订数据的结构化表示,简化了后续的格式化和展示操作。

在创建了booking_info对象后,生成一个名为data的新字典。该字典旨在以适合转换为Excel表格的格式结构化数据。

字典由两对键值对组成:

  • 第一对使用空字符串作为键,并包含一个包含两个标题值“总预订量”和“总金额(美元)”的列表。
  • 第二对使用booking_info.get_timestamp()获取的时间戳作为键,并包括一个包含两个元素的列表:预订总数的值(booking_info.get_total_bookings())和预订总金额的值(booking_info.get_total_amount())。

此字典允许将数据插入到Excel表格中:

Screenshot-2023-10-29-135512
示例Excel表格

然后,将经过结构化的data字典转换为名为df的pandas DataFrame。DataFrames是Python中常用的处理表格数据的数据结构。此步骤简化了数据的操作和导出,以供进一步处理或可视化。

为创建Excel表格,代码使用带有“xlsxwriter”引擎的pd.ExcelWriter上下文管理器。此上下文管理器确保Excel文件已适当准备好进行数据插入。通过提供sheet_name参数以指定Excel文件中的工作表名称。

然后,将DataFrame df中的数据写入Excel表格。使用to_excel方法与writer对象,将index参数设置为False。这样的配置不包括通常包含在Excel表格中的默认行编号。

如何结合功能

现在让我们编写一个公共方法,用户可以使用该方法从数据库中提取数据并将提取的数据转换为Excel表格文件。

...class DataExporter:	    ...        def generate_excelsheet(        self,        start_timestamp: datetime,        end_timestamp: datetime,        sheet_name: str = "Bookings Data.xlsx",    ) -> bool:        """        为指定的时间范围生成一个包含预订数据的Excel表格。        参数:            start_timestamp (datetime):时间范围的开始。            end_timestamp (datetime):时间范围的结束。            sheet_name (str, 可选):要创建的Excel表格的名称。默认为"Bookings Data.xlsx"。        返回:            bool:如果成功生成表格,则为True;否则为False。        注意:            此方法记录错误,但不抛出异常,以避免中断工作流程。        """        data = self.__fetch_from_database(start_timestamp, end_timestamp)        if data is not None:            self.__convert_to_excelsheet(data, sheet_name)            return True        else:            logging.error("没有数据可用于生成表格")            return False

该方法接受几个参数,包括start_timestampend_timestamp,用于定义数据提取的时间段的起始和结束。还有一个可选的sheet_name参数,允许用户指定Excel表格的名称。默认情况下,表格的名称为”Bookings Data.xlsx”,提供了一个方便的默认选项。

在执行时,该方法通过调用类的内部私有方法__fetch_from_database来启动数据检索过程,并传入指定的时间范围。

如果数据检索成功且数据可用,该方法将继续调用__convert_to_excelsheet方法,对数据进行结构化和格式化,以便插入Excel表格中。

另一方面,如果所提供的时间范围内没有可用数据,该方法将记录错误消息并返回”False”,表示Excel表格生成失败。

如何通过邮件发送预订数据报告

在本节中,您将学习如何使用Python将预订数据报告作为附件发送邮件。

创建一个名为mailer.py的文件,并添加以下内容:

import loggingimport osimport smtplibimport sslfrom email import encodersfrom email.mime.base import MIMEBasefrom email.mime.multipart import MIMEMultipartfrom email.mime.text import MIMETextlogging.basicConfig(    format="%(asctime)s | %(levelname)s : %(message)s", level=logging.INFO)SMTP_SERVER = os.environ.get("SMTP_SERVER")PORT = os.environ.get("EMAIL_PORT")EMAIL = os.environ.get("EMAIL")PASSWORD = os.environ.get("PASSWORD")def send_email(to_email: str, subject: str, attachment_name: str):    """    向指定收件人发送带附件的电子邮件。    参数:        to_email (str):收件人的电子邮件地址。        subject (str):电子邮件的主题。        attachment_name (str):附件的文件名。    注意:        此函数假设SMTP服务器需要TLS加密。    引发:        smtplib.SMTPException:如果发送电子邮件时出现问题。    """    message = MIMEMultipart()    message["From"] = EMAIL    message["To"] = to_email    message["Subject"] = subject    body = "嗨,\n\n请查看附件中的报告。\n\n谢谢"    message.attach(MIMEText(body, "plain"))    with open(attachment_name, "rb") as file:        part = MIMEBase(            "application", "vnd.openxmlformats-officedocument.spreadsheetml.sheet"        )        part.set_payload(file.read())    encoders.encode_base64(part)    part.add_header(        "Content-Disposition",        f"attachment; filename= {attachment_name}",    )    logging.info(f"将附件 {attachment_name} 添加到邮件中")    message.attach(part)    text = message.as_string()    context = ssl.create_default_context()    with smtplib.SMTP(SMTP_SERVER, PORT) as server:        logging.info(f"向 {to_email} 发送电子邮件")        server.starttls(context=context)        server.login(EMAIL, PASSWORD)        server.sendmail(EMAIL, to_email, text)        logging.info(f"成功发送电子邮件至 {to_email}")

像往常一样,我们在脚本中配置了日志记录器和环境变量。

核心功能被封装在send_email函数中。这个函数接受三个参数:

  1. to_email: 收件人的电子邮箱地址。
  2. subject: 电子邮件的主题。
  3. attachment_name: 附件的文件名,在这种情况下应该是预订数据报告。

在函数内部,我们使用MIMEMultipart类构建了一条电子邮件信息。这个信息包括发件人的电子邮箱地址,收件人的电子邮箱地址,主题以及一个包含简单消息的纯文本正文。

脚本允许将预订数据报告作为附件发送。它读取附件文件,对其进行编码,并将其添加到电子邮件信息中。这样确保收件人可以轻松地从电子邮件中访问和下载数据报告。

你可以在这里学习如何在使用Python发送电子邮件时添加附件。

ssl库的create_default_context函数会为电子邮件通信创建一个安全的SSL上下文。最后,脚本连接到SMTP服务器,使用发件人的电子邮箱地址和密码进行登录,发送电子邮件,并在成功传输时记录成功消息。

如何测试应用程序的流程

让我们最终测试一下应用程序的流程。

finally-about-time

在本节中,我们将自动处理每月的报告。创建一个main.py文件,并添加以下内容:

from exporter import DataExporterfrom datetime import datetimefrom mailer import send_emailstart_timestamp = datetime(2023, 5, 28, 00, 00, 00)  # 2023年5月28日 00:00:00end_timestamp = datetime(2023, 8, 20, 23, 59, 59)  # 2023年8月20日 23:59:59exporter = DataExporter()if exporter.generate_excelsheet(        start_timestamp, end_timestamp, sheet_name="预订数据.xlsx"):    send_email("[email protected]", "您的报告", "预订数据.xlsx")

在上面的代码中,我们创建了两个时间戳对象start_timestampend_timestamp,以指定一个时间范围。我们将开始日期设置为2023年5月28日午夜,结束日期设置为2023年8月20日午夜前。

接下来,我们创建了一个DataExporter类的实例,该实例处理数据导出和Excel表格生成。使用之前定义的时间戳调用此实例的generate_excelsheet方法,以创建与预订相关的报告。

最后,代码使用send_email函数将生成的Excel表格作为附件发送电子邮件。

如何安排应用程序

接下来,我们的目标是自动化报告调度过程。我们计划在每个星期一定时发送上周数据的报告,并在每个月的第一天发送上个月的信息。

要安排执行,您需要安装schedule库:

pip install schedule

一旦安装了该库,下面是如何自动化每月和每周报告的方法:

import schedulefrom exporter import DataExporterfrom datetime import datetime, timedeltafrom mailer import send_emaildef main():    today = datetime.now()    sheet_name = "Bookings Data.xlsx"    if today.weekday() == 0:  # 检查是否为星期一(0表示星期一)        # 是星期一,获取上一周的数据(从星期一到星期日)        start_timestamp = (today - timedelta(days=7)                           ).replace(hour=0, minute=0, second=0, microsecond=0)        end_timestamp = (today - timedelta(days=1)                         ).replace(hour=23, minute=59, second=59, microsecond=0)        sheet_name = "每周报告.xlsx"    elif today.day == 29:        # 是每月的第一天,获取上个月的数据        start_timestamp = (today.replace(day=1) - timedelta(days=1)                           ).replace(day=1, hour=0, minute=0, second=0, microsecond=0)        end_timestamp = (today.replace(day=1) - timedelta(days=1)                         ).replace(hour=23, minute=59, second=59, microsecond=0)        sheet_name = "每月报告.xlsx"    exporter = DataExporter()    exporter.generate_excelsheet(        start_timestamp, end_timestamp, sheet_name)    send_email("[email protected]",               "您的报告", sheet_name)schedule.every().day.at("00:00").do(main)while True:    schedule.run_pending()

上述脚本使用schedule库,在午夜时分每天运行main函数。 main函数用于计算提取数据和生成Excel表格的时间戳。生成Excel表格后,脚本会通过电子邮件发送给指定的接收者。

如果脚本在周一运行,则设置生成每周报告。它会计算先前一周的start_timestampend_timestampstart_timestamp设置为前一周的周一午夜(00:00:00),而end_timestamp设置为前一周的周日午夜前(23:59:59)。 Excel表格名为“周报.xlsx”。

在每月的第一天,脚本会将重点转移到生成每月报告上。它会计算start_timestampend_timestamp以包含整个上个月的时间范围。 start_timestamp设置为前一个月的第一天午夜(00:00:00),而end_timestamp设置为前一个月的最后一天午夜前(23:59:59)。 Excel表格名为“月报.xlsx”。

总结

在本教程中,您学习了如何利用Python自动化生成报告并发送给电子邮件接收者。我希望您觉得本教程有所帮助!

未来展望

  • 您可以将电子邮件接收者添加到数据库中,并从那里获取列表,而不是直接在代码中硬编码。这将使应用程序更具配置性。
  • 您还可以使用Cron作业在每天午夜自动执行脚本。在这种情况下,您将不需要schedule库。

这是Github代码仓库的链接


Leave a Reply

Your email address will not be published. Required fields are marked *