如何使用Python自动化数据导出并发送电子邮件报告 – 一步步指南
如何使用Python自动导出数据和发送电子邮件报告-一步一步指南
在今天数据驱动的世界中,自动化是简化任务和节省时间的关键。在这个适合初学者的教程中,我将带你逐步介绍如何使用Python自动从PostgreSQL数据库导出数据并将其作为附件发送到电子邮件。
这个分步指南将帮助你掌握与数据库、数据操作和电子邮件通信相关的基础知识,并通过Python脚本实现自动化。
商业背景
想象一下,你是一个组织中的一员,你的经理期望每周报告中充满有价值的见解。但是创建这个报告远非一项直截了当的任务。
为了获取所需的信息,你必须手动执行十个不同的数据库查询,收集结果,然后仔细地将它们编译成Excel电子表格。这是一个耗时且容易出错的过程,可能会让你筋疲力尽。
在这种情况下,如果Python代替你掌控整个过程,是否会是一个改变游戏规则的机会?
想象一下:每周都没有人为干预,Python无缝地提取所需数据,将其编译成整洁的Excel表格,甚至准时发送给你的经理。
本教程将帮助你学习如何做到这一点。我将引导你逐步完成自动化这个过程,让你的每周或每月报告轻松自如,让你有更多时间专注于更重要的任务。
目录
- 准备条件
- 如何设置你的虚拟环境
- 如何设置你的示例数据库
- 如何设置日志记录和环境变量
- 如何从数据库中提取数据
- 如何使用
BookingInfo
类结构化预订数据 - 如何将数据转换为Excel表格
- 如何合并功能
- 如何发送带有预订数据报告的电子邮件
- 如何测试流程
- 如何安排应用程序
- 总结
准备条件
在开始之前,请确保你具备以下条件:
- 在您的计算机上安装了Python。您可以从Python.org下载Python。
- 基本的Python编程语言知识
- 熟悉在Python中发送电子邮件
- 在您的计算机上安装了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”的演示数据库,我们将在整个教程中使用它。该数据库包含三个表:bookings
、flights
和airports_data
。
我将为你提供一个名为airlines_db.sql
的SQL脚本文件,该文件将创建数据库并用示例数据填充。要设置数据库,你需要在系统上安装PostgreSQL。
下载并安装数据库
- 从这里下载SQL脚本文件”airlines_db.sql”。
- 打开你的终端或命令提示符。
- 使用以下命令安装数据库。确保你已经安装了PostgreSQL的命令行工具,且可以访问
psql
命令。如果你的PostgreSQL用户名不同,请将postgres
替换为你的用户名。
psql -f airlines_db.sql -U postgres
这个命令将执行SQL脚本,并创建带有bookings
、flights
和airports_data
表的”airlines”数据库。
模式说明
数据库中的主要模式是bookings
。让我们更详细地看一下”airlines”数据库中的表:
表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_airport
和arrival_airport
字段以character(3)
类型分别存储出发和到达机场代码。
status
字段是一个character varying(20)
,记录航班的状态,必须是 ‘On Time’、’Delayed’、’Departed’、’Arrived’、’Scheduled’或’Cancelled’之一。该表还包括预定的出发和到达时间字段(scheduled_departure
和scheduled_arrival
)以及实际的出发和到达时间字段(actual_departure
和actual_arrival
)。
此外,此表建立了两个关键的外键:flights_arrival_airport_fkey
和 flights_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_fkey
和 flights_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
,这意味着记录信息性的消息。您还可以使用更高的严重级别,如WARNING
或ERROR
,处理更严重的问题。
您可以在此教程中了解有关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_timestamp
和end_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_info
的BookingInfo
对象。该BookingInfo
对象提供了预订数据的结构化表示,简化了后续的格式化和展示操作。
在创建了booking_info
对象后,生成一个名为data
的新字典。该字典旨在以适合转换为Excel表格的格式结构化数据。
字典由两对键值对组成:
- 第一对使用空字符串作为键,并包含一个包含两个标题值“总预订量”和“总金额(美元)”的列表。
- 第二对使用
booking_info.get_timestamp()
获取的时间戳作为键,并包括一个包含两个元素的列表:预订总数的值(booking_info.get_total_bookings()
)和预订总金额的值(booking_info.get_total_amount()
)。
此字典允许将数据插入到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_timestamp
和end_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
函数中。这个函数接受三个参数:
to_email
: 收件人的电子邮箱地址。subject
: 电子邮件的主题。attachment_name
: 附件的文件名,在这种情况下应该是预订数据报告。
在函数内部,我们使用MIMEMultipart
类构建了一条电子邮件信息。这个信息包括发件人的电子邮箱地址,收件人的电子邮箱地址,主题以及一个包含简单消息的纯文本正文。
脚本允许将预订数据报告作为附件发送。它读取附件文件,对其进行编码,并将其添加到电子邮件信息中。这样确保收件人可以轻松地从电子邮件中访问和下载数据报告。
你可以在这里学习如何在使用Python发送电子邮件时添加附件。
ssl
库的create_default_context
函数会为电子邮件通信创建一个安全的SSL上下文。最后,脚本连接到SMTP服务器,使用发件人的电子邮箱地址和密码进行登录,发送电子邮件,并在成功传输时记录成功消息。
如何测试应用程序的流程
让我们最终测试一下应用程序的流程。
在本节中,我们将自动处理每月的报告。创建一个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_timestamp
和end_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_timestamp
和end_timestamp
。 start_timestamp
设置为前一周的周一午夜(00:00:00),而end_timestamp
设置为前一周的周日午夜前(23:59:59)。 Excel表格名为“周报.xlsx”。
在每月的第一天,脚本会将重点转移到生成每月报告上。它会计算start_timestamp
和end_timestamp
以包含整个上个月的时间范围。 start_timestamp
设置为前一个月的第一天午夜(00:00:00),而end_timestamp
设置为前一个月的最后一天午夜前(23:59:59)。 Excel表格名为“月报.xlsx”。
总结
在本教程中,您学习了如何利用Python自动化生成报告并发送给电子邮件接收者。我希望您觉得本教程有所帮助!
未来展望
- 您可以将电子邮件接收者添加到数据库中,并从那里获取列表,而不是直接在代码中硬编码。这将使应用程序更具配置性。
- 您还可以使用Cron作业在每天午夜自动执行脚本。在这种情况下,您将不需要
schedule
库。
Leave a Reply