You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 19:27:35