Python ValueError: 已关闭文件上的I/O操作问题求助
问题修复方案
错误根源
- 多余的文件句柄:你手动执行了
file = open(filepath, 'r')但未使用或关闭该句柄,和openpyxl的文件操作产生资源冲突,安装Pillow后,openpyxl对文件资源的处理逻辑更严格,这个冲突被触发。 - 循环内过早关闭工作簿:
for循环里每次保存后就调用wb.close(),第二次循环时工作簿已关闭,后续操作自然触发"已关闭文件的I/O操作"错误。
修改后的完整代码
from tkinter import filedialog, tk, font from openpyxl import load_workbook from openpyxl.worksheet.datavalidation import DataValidation from pathlib import Path import pyautogui def openFile(): filepath = filedialog.askopenfilename( title="Please select a file", filetypes = (('Excel files', '*.xlsx'), ('Excel macro files', '*.xlsm')) ) # 移除多余的手动文件打开语句,openpyxl会自行处理文件资源 wb = load_workbook(filepath, read_only=False, keep_vba=True) ws=wb.active fileonly = filepath.split('/')[-1] filewithoutextension = fileonly.split('-')[0] fileextension = fileonly.split('.')[-1] y = pyautogui.prompt(text='Please specify the number of file duplicates', title='Number of files', default='2') if not y: # 处理用户取消输入的情况 return try: y_int = int(y) if y_int < 2: pyautogui.alert("Please enter a number greater than or equal to 2") return except ValueError: pyautogui.alert("Please enter a valid integer") return file_path = filedialog.askdirectory() if not file_path: # 处理用户取消选择目录的情况 return # 所有复制任务完成后再关闭工作簿,避免循环内提前关闭导致后续操作失败 for x in range(2, y_int + 1): newname = "%03d" % x dv = DataValidation(type="list", formula1='"COLLECTION,INTER PROJECT COLLECTION,INTER PROJECT TRANSFER,TRANSFER"', allow_blank=False) dv.error = 'Please select entry from the list!' c1 = ws["D4"] c1.value = "COLLECTION" dv.add(c1) ws.add_data_validation(dv) save_path = Path(file_path) / f"{filewithoutextension}- {newname}.{fileextension}" wb.save(save_path) print(f"{filewithoutextension}- {newname}.{fileextension}") wb.close() rootwindow = tk.Tk() rootwindow.geometry("500x100") rootwindow.title("Excel file duplicator") font.families() windowfont=tk.font.nametofont("TkDefaultFont") windowfont.config( family="Segoe Script", size=24, weight=font.BOLD) button = tk.Button(rootwindow, text='Open Excel document',command=openFile, fg='black', bg='yellow') button.pack() rootwindow.mainloop()
关键修改点
- 移除多余的文件打开语句:删掉
file = open(filepath, 'r'),openpyxl的load_workbook会自行负责文件的打开和资源释放,手动打开的句柄会干扰其正常操作。 - 调整工作簿关闭时机:将
wb.close()从循环内移到循环外,确保所有复制任务完成后再关闭工作簿,避免后续循环操作已关闭的资源。 - 增加输入校验:处理用户输入非数字、取消输入或输入小于2的情况,避免程序因非法输入崩溃。
内容的提问来源于stack exchange,提问作者Geographos
相关产品推荐
相关产品推荐

