使用Python从MySQL导出指定日期范围数据至Excel
解决MySQL按日期范围导出数据到Excel的问题
原代码存在的问题
- 结束日期的标签文本错误:重复使用
Select Start Date,应改为Select End Date - SQL语句语法错误:直接在SQL字符串中调用Python组件方法
StartDate.get_date(),数据库无法识别Python代码,需先获取日期值再传入查询 - 数据库连接未正确管理:原代码未关闭数据库连接,可能导致连接泄漏;且未使用参数化查询,存在SQL注入风险
修正后的完整代码
from tkinter import Tk, Canvas, Label, Button, messagebox from tkcalendar import DateEntry import pandas as pd import mysql.connector def img_resource_path(icon_name): # 保留你原有的资源路径处理逻辑 return icon_name class PrintbyDate(Tk): def __init__(self): super().__init__() self.maxsize(400, 200) self.minsize(400, 200) self.iconbitmap(img_resource_path("chegutuicon.ico")) self.title("Export Report for a specific date range.") self.canvas = Canvas(width=1366, height=768, bg='gray') self.canvas.pack() # 开始日期选择 self.start_date = DateEntry(self, date_pattern='YYYY-MM-DD') self.start_date.place(x=200, y=50) Label(self, text='Select Start Date:', bg='gray', font=('Courier new', 10, 'bold')).place(x=70, y=50) # 结束日期选择(修正标签文本) self.end_date = DateEntry(self, date_pattern='YYYY-MM-DD') self.end_date.place(x=200, y=100) Label(self, text='Select End Date:', bg='gray', font=('Courier new', 10, 'bold')).place(x=70, y=100) Button(self, text='Print', width=15, font=('arial', 10), command=self.export_data).place(x=70, y=130) def export_data(self): # 获取日期值并转为数据库兼容的字符串格式 start = self.start_date.get_date().strftime('%Y-%m-%d') end = self.end_date.get_date().strftime('%Y-%m-%d') # 使用with语句自动管理数据库连接,避免连接泄漏 try: with mysql.connector.connect( user="ngonex", passwd="2007Ngonidzashe", host="localhost", database="complains_database" ) as con: # 参数化查询,避免SQL注入,同时解决原代码的语法错误 query = 'SELECT * FROM client WHERE DateReported BETWEEN %s AND %s' df = pd.read_sql(query, con, params=(start, end)) print(df) # 导出到Excel,去掉默认索引列 df.to_excel('complains_report.xlsx', index=False) messagebox.showinfo("Successful", "Report generated successfully check output folder!") except Exception as e: messagebox.showerror("Error", f"Failed to generate report: {str(e)}") if __name__ == "__main__": app = PrintbyDate() app.mainloop()
关键修改说明
- 修正标签文本:将结束日期对应的Label文本改为
Select End Date,避免用户混淆 - 日期值处理:先通过
get_date()获取datetime对象,再用strftime格式化为MySQL兼容的日期字符串 - 参数化SQL查询:使用
%s作为占位符,通过params传递日期参数,既解决了原代码的语法错误,又避免了SQL注入风险 - 数据库连接管理:使用
with语句自动管理连接生命周期,无需手动关闭连接,防止连接泄漏 - 异常处理:添加
try-except捕获数据库连接、查询、导出过程中可能出现的错误,通过弹窗提示用户具体问题 - 组件属性优化:将日期选择器改为实例属性,方便在类方法中访问,同时移除了未使用的
StringVar变量
内容的提问来源于stack exchange,提问作者Ngonidzashe
相关产品推荐
相关产品推荐

