Python TKinter生成PDF时如何添加日期时间后缀避免文件覆盖?
问题
我使用Python的Tkinter框架开发了PDF报表生成程序,每次点击报表按钮生成PDF时,新文件都会覆盖目录中已有的同名PDF。请问如何修改代码,使生成的PDF在同一目录下保留基础文件名,并添加不同日期和时间后缀以避免覆盖?
原代码
from tkinter import * from reportlab.pdfgen import canvas from reportlab.lib.units import inch from reportlab.lib.pagesizes import letter, A4 from T_invoice import my_templet import sqlite3 import subprocess import tkinter as tk my_w = tk.Tk() my_w.geometry("900x650") my_w.title("christ") def PDFPrint(): my_path = ("E:\my_pdf.pdf") c = canvas.Canvas(my_path, pagesize=letter) c = my_temp(c) c.setFillColorRGB(0, 0, 1) c.setFont("Helvetica", 14) row_gap = 0.3 line_y = 7.9 total = 0 conn = sqlite3.connect("E:\login.db") con = conn.cursor() query = ("select * from sales ") con.execute(query) saleslist = con.fetchall() for i in range(0, len(saleslist)): saleslist[i] = list(saleslist[i]) con.execute("select product_d,product_p from products where product_id=?", (int(saleslist[i][2]),)) l = con.fetchall() s = (str(saleslist[i][4])).split('-') saleslist[i][4] = s[2] + " - " + s[1] + " - " + s[0] saleslist[i]=[saleslist[i][0], saleslist[i][1], saleslist[i][2], l[0][0], saleslist[i][3],l[0][1] * 1, saleslist[i][4], saleslist[i][5]] saleslist[i] = tuple(saleslist[i]) for dt in saleslist: c.drawString(0.1 * inch, line_y * inch, str(dt[3])) c.drawRightString(4.5 * inch, line_y * inch, str(dt[5])) c.drawRightString(5.5 * inch, line_y * inch, str(dt[4])) sub_total = round( (dt[5] * dt[4]), 1) c.drawRightString(7 * inch, line_y * inch, str(sub_total)) total = round(total + sub_total, 2) line_y = line_y - row_gap total_final = total c.setFont("Times-Bold", 22) c.setFillColorRGB(1, 0, 0) c.drawRightString(7 * inch, -0.3 * inch, str(total_final)) c.showPage() c.save() subprocess.Popen(["E:\\pdf\\my_pdf.pdf"], shell=True) reportbut = Button(my_w, text="report", font="roboto 14", bd=5, width=8, bg="yellow",command=PDFPrint) reportbut.place(x=510, y=18, height=40) my_w.mainloop()
修改方案
核心思路
通过datetime模块获取当前时间,生成YYYYMMDD_HHMMSS格式的时间戳,拼接在基础文件名后,确保每个PDF文件名唯一,同时修正原代码中的语法错误。
修改后的完整代码
from tkinter import * from reportlab.pdfgen import canvas from reportlab.lib.units import inch from reportlab.lib.pagesizes import letter, A4 from T_invoice import my_templet import sqlite3 import subprocess import tkinter as tk # 新增:导入datetime模块生成时间戳 from datetime import datetime my_w = tk.Tk() my_w.geometry("900x650") my_w.title("christ") def PDFPrint(): # 生成当前时间戳,格式为YYYYMMDD_HHMMSS,避免特殊字符 timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") # 拼接带时间戳的文件名,确保唯一 my_path = f"E:\\my_pdf_{timestamp}.pdf" c = canvas.Canvas(my_path, pagesize=letter) c = my_temp(c) c.setFillColorRGB(0, 0, 1) c.setFont("Helvetica", 14) row_gap = 0.3 line_y = 7.9 total = 0 conn = sqlite3.connect("E:\\login.db") con = conn.cursor() query = "select * from sales" con.execute(query) saleslist = con.fetchall() for i in range(len(saleslist)): saleslist[i] = list(saleslist[i]) con.execute("select product_d,product_p from products where product_id=?", (int(saleslist[i][2]),)) l = con.fetchall() # 增加异常处理,避免日期格式错误导致崩溃 try: s = str(saleslist[i][4]).split('-') if len(s) == 3: saleslist[i][4] = f"{s[2]} - {s[1]} - {s[0]}" except IndexError: pass saleslist[i] = [ saleslist[i][0], saleslist[i][1], saleslist[i][2], l[0][0], saleslist[i][3], l[0][1] * 1, saleslist[i][4], saleslist[i][5] ] saleslist[i] = tuple(saleslist[i]) for dt in saleslist: c.drawString(0.1 * inch, line_y * inch, str(dt[3])) c.drawRightString(4.5 * inch, line_y * inch, str(dt[5])) c.drawRightString(5.5 * inch, line_y * inch, str(dt[4])) sub_total = round(dt[5] * dt[4], 1) c.drawRightString(7 * inch, line_y * inch, str(sub_total)) total = round(total + sub_total, 2) line_y -= row_gap total_final = total c.setFont("Times-Bold", 22) c.setFillColorRGB(1, 0, 0) c.drawRightString(7 * inch, -0.3 * inch, str(total_final)) c.showPage() c.save() # 同步更新打开路径为刚生成的带时间戳的文件 subprocess.Popen([my_path], shell=True) reportbut = Button(my_w, text="report", font="roboto 14", bd=5, width=8, bg="yellow",command=PDFPrint) reportbut.place(x=510, y=18, height=40) my_w.mainloop()
关键修改点说明
- 导入
datetime模块,生成无特殊字符的时间戳,确保文件名合法且唯一 - 用f-string拼接文件名,生成类似
E:\my_pdf_20240520_143025.pdf的唯一路径 - 修正原代码中的语法错误:中文引号、SQL参数传递格式、路径转义问题
- 增加日期格式异常处理,避免程序崩溃
- 同步更新PDF打开路径,确保打开的是最新生成的文件
内容的提问来源于stack exchange,提问作者Maliamungu
相关产品推荐
相关产品推荐

