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

Tkinter发票录入GUI生成CSV仅表头无数据问题求助

发票信息录入CSV导出工具问题修复

问题描述

开发了一款用于录入发票信息并导出至CSV的Tkinter GUI,该CSV将导入会计软件,需保证数据与表头对应。目前仅能生成CSV表头,无法写入数据。预期流程为:用户录入数据后点击Export将数据加入列表,再点击Save写入CSV,且每次操作可追加新行。打印显示列表已生成,但数据无法写入CSV。

错误分析

  • 数据列数不匹配:表头包含9个字段,但Add函数中构建的data_list仅包含8个字段,缺失invoice_number.get(),导致CSV写入时数据行与表头列数不一致,无法正常显示数据。
  • 表头语法错误:表头中的"Invoice Date,"多了一个逗号,会导致会计软件导入时字段识别异常。
  • 文件写入模式问题:当前Save函数使用"w"模式打开文件,每次保存会清空原有内容重新写入;若要追加新行,需判断文件是否存在,不存在则写入表头,存在则仅追加数据。

修复后的完整代码

from csv import writer
from tkinter import *
from tkinter import messagebox
import os

window=Tk()
window.title("Data Entry")
window.geometry("800x400")
main_list=[]

# 按钮功能函数
def Add():
    global main_list
    # 补全缺失的invoice_number字段,保证列数与表头一致
    data_list=[
        vendor_ID.get(),
        invoice_number.get(),
        description.get(),
        invoice_amount.get(),
        invoice_date.get(),
        due_date.get(),
        post_date.get(),
        dist_amount.get(),
        dist_account_num.get()
    ]
    main_list.append(data_list)
    messagebox.showinfo("Information","数据已成功添加")
    print(data_list)
    print(main_list)

def Save():
    csv_file = "InvoiceImport.csv"
    # 定义正确的表头,移除多余逗号
    header = [
        "Vendor ID",
        "Invoice Number",
        "Description",
        "Invoice Amount",
        "Invoice Date",
        "Due Date",
        "Post Date",
        "Invoice Distribution Amount",
        "Invoice Distribution Debit account number"
    ]
    
    file_exists = os.path.isfile(csv_file)
    # 根据文件是否存在选择写入模式,存在则追加(a),不存在则新建写入(w)
    with open(csv_file, "a", newline="") as file:
        csv_writer = writer(file)
        # 仅当文件不存在时写入表头
        if not file_exists:
            csv_writer.writerow(header)
        # 写入所有新增数据
        csv_writer.writerows(main_list)
        # 写入后清空main_list,避免重复保存同一批数据
        main_list.clear()
    messagebox.showinfo("Information", "保存成功")

def Clear():
    vendor_ID.delete(0,END)
    invoice_number.delete(0,END)
    description.delete(0,END)
    invoice_amount.delete(0, END)
    invoice_date.delete(0, END)
    due_date.delete(0, END)
    post_date.delete(0, END)
    dist_amount.delete(0, END)
    dist_account_num.delete(0, END)


# 框架设置
left_frame = Frame(window)
middle_frame= Frame(window)
right_frame = Frame(window)
bottom_frame = Frame(window)

# 标签设置
label1 = Label(left_frame, text="Vendor ID: ",padx=20,pady=10)
label2 = Label(left_frame, text="Invoice number: ",padx=20,pady=10)
label3 = Label(left_frame, text="Description: ",padx=20,pady=10)
label4 = Label(left_frame, text="Invoice Amount: ",padx=20,pady=10)
label5 = Label(left_frame, text="Invoice Date: ",padx=20,pady=10)
label6 = Label(middle_frame, text="Due date: ",padx=20,pady=10)
label7 = Label(middle_frame, text="Post date: ",padx=20,pady=10)
label8 = Label(middle_frame, text="Invoice Distribution Amount: ",padx=20,pady=10)
label9 = Label(middle_frame, text="Invoice Distribution Debit account number: ",padx=20,pady=10)
label10 = Label(middle_frame, text=" ",padx=20,pady=10)


label1.grid(row=0, column=0)
label2.grid(row=1, column=0)
label3.grid(row=2, column=0)
label4.grid(row=3, column=0)
label5.grid(row=4, column=0)
label6.grid(row=0, column=0)
label7.grid(row=1, column=0)
label8.grid(row=2, column=0)
label9.grid(row=3, column=0)
label10.grid(row=4, column=0)


# 输入框设置
vendor_ID=Entry(left_frame, width=30,borderwidth=3)
invoice_number=Entry(left_frame, width=30,borderwidth=3)
description=Entry(left_frame, width=30,borderwidth=3)
invoice_amount=Entry(left_frame, width=30,borderwidth=3)
invoice_date=Entry(left_frame, width=30,borderwidth=3)
due_date=Entry(middle_frame, width=30,borderwidth=3)
post_date=Entry(middle_frame, width=30,borderwidth=3)
dist_amount=Entry(middle_frame, width=30,borderwidth=3)
dist_account_num=Entry(middle_frame, width=30,borderwidth=3)

# 按钮设置
save=Button(bottom_frame, text="Save",padx=20,pady=10,command=Save)
add=Button(bottom_frame, text="Export",padx=20,pady=10,command=Add)
clear=Button(bottom_frame, text="Clear",padx=18,pady=10,command=Clear)
Exit=Button(bottom_frame, text="Exit",padx=20,pady=10,command=window.quit)

left_frame.grid(row=0, column=0)
middle_frame.grid(row=0, column=1)
right_frame.grid(row=0, column=2)
bottom_frame.grid(row=1, column=0)

vendor_ID.grid(row=0,column=1)
invoice_number.grid(row=1,column=1)
description.grid(row=2,column=1)
invoice_amount.grid(row=3,column=1)
invoice_date.grid(row=4,column=1)
due_date.grid(row=0,column=1)
post_date.grid(row=1,column=1)
dist_amount.grid(row=2,column=1)
dist_account_num.grid(row=3,column=1)

save.grid(row=1,column=0,columnspan=2)
add.grid(row=2,column=0,columnspan=2)
clear.grid(row=3,column=0,columnspan=2)
Exit.grid(row=4,column=0,columnspan=2)

window.mainloop()

关键修复点说明

  1. 补全数据字段:在Add函数的data_list中加入invoice_number.get(),确保数据列数与表头一致,解决数据无法写入的核心问题。
  2. 修正表头错误:移除"Invoice Date,"末尾的逗号,保证字段名称符合会计软件导入要求。
  3. 优化文件写入逻辑:
    • 使用os.path.isfile判断文件是否存在,首次创建时写入表头,后续保存仅追加新数据。
    • 写入后清空main_list,避免重复保存同一批数据。
    • 打开文件时添加newline="",避免CSV生成多余空行。

内容的提问来源于stack exchange,提问作者NaterVater none

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 06:45:37