我正在尝试使用openpyxl保存Excel文件,执行代码后出现此错误。
我的代码:
def assemble_files(self):
global names
wb = load_workbook(names[0])
sheet = wb.get_active_sheet()
exportFile = asksaveasfilename( defaultextension=".xlsx", filetypes=(("Excel file", "*.xlsx"),("All Files", "*.*") ))
wb.save(exportFile)
messagebox.showinfo("Information", "Files successfully assembled")`
错误:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\mohamed.louati\AppData\Local\Programs\Python\Python36\lib\tkinter\__init__.py", line 1699, in __call__
return self.func(*args)
File "C:\Users\mohamed.louati\Desktop\aines\ID_Extractor.py", line 98, in assemble_files
wb.save(exportFile)
File "C:\Users\mohamed.louati\AppData\Local\Programs\Python\Python36\lib\site-packages\openpyxl\writer\excel.py", line 180, in _write_comment
vml = fromstring(self.workbook.vba_archive.read(ws.legacy_drawing))
AttributeError: 'NoneType' object has no attribute 'read'
任何人都可以解决这个问题
答案 0 :(得分:-1)
您的exportFile
似乎没有。
asksaveasfilename
函数将提示保存文件对话框。如果由于某种原因失败,则可能是您的问题。您可以尝试添加对返回值的检查。
答案 1 :(得分:-1)
这是完整的代码:
# -*- coding: utf-8 -*-
import tkinter as tk
import tkinter.ttk as ttk
from tkinter.filedialog import askopenfilename,askopenfilenames,asksaveasfilename
from tkinter import messagebox
import xlrd
from openpyxl import *
from openpyxl.styles.borders import Border, Side
name = None
names = None
class Application(tk.Frame):
def __init__(self, container):
super().__init__(container)
self.container = container
self.document = None
self.name_sheet = None
self.type_sheet = "Type1"
self.code = ""
self.widgets()
def list_paterns(self,document):
feuilles = []
res = len(document.sheet_names())
names = document.sheet_names()
for i in range(res):
feuilles.append(document.sheet_by_index(i))
return feuilles,names
def widgets(self):
menu = tk.Menu(self.container)
root.config(menu=menu)
filemenu = tk.Menu(menu, tearoff=0)
menu.add_cascade(label="File", menu=filemenu)
filemenu.add_command(label="Generate", command = self.generate)
filemenu.add_command(label="Assemble", command = self.assemble)
filemenu.add_separator()
filemenu.add_command(label="Exit", command = self.do_exit)
def generate(self):
liste = self.container.winfo_children()
for item in liste :
if item.winfo_children() :
liste.extend(item.winfo_children())
for item in liste:
item.place_forget()
load = tk.Button(self.container,text="Load file",command=self.load_template, width = 10)
load.place(x=20,y=20)
generate_type = tk.Button(self.container,text="Generate", command= lambda: self.generate_code(self.name_sheet), width = 10)
generate_type.place(x=250,y=20)
def assemble(self):
liste = self.container.winfo_children()
for item in liste :
if item.winfo_children() :
liste.extend(item.winfo_children())
for item in liste:
item.place_forget()
load = tk.Button(self.container,text="Select files",command=self.load_files, width = 10)
load.place(x=20,y=20)
assemble = tk.Button(self.container,text="Assemble", command= self.assemble_files, width = 10)
assemble.place(x=250,y=20)
def do_exit(self):
root.destroy()
def load_files(self):
""" load files """
global names
names = askopenfilenames(parent=root,title='Choose a file')
def assemble_files(self):
""" assemble files """
global names
wb = load_workbook(names[0])
sheet = wb.get_active_sheet()
for file in names:
wb1 = load_workbook(file)
current = wb1.worksheets[0]
for lin in range(1,current.max_row+1):
for col in range(1,current.max_column+1):
if (hasattr(current.cell(row=lin, column=col), "value")):
if current.cell(row=lin, column=col).value != sheet.cell(row=lin, column=col).value and current.cell(row=lin, column=col).value != None:
sheet.cell(row=lin, column=col).value = current.cell(row=lin, column=col).value
exportFile = asksaveasfilename( defaultextension=".xlsx", filetypes=(("Excel file", "*.xlsx"),("All Files", "*.*") ))
print(sheet.cell(row=27, column=5).value)
wb.save(exportFile)
messagebox.showinfo("Information", "Files successfully assembled")
def load_template(self):
global name
def name_sheet(event):
self.name_sheet = event.widget.get()
def type_sheet(event1):
self.type_sheet = event1.widget.get()
name = askopenfilename() #select file
self.document = xlrd.open_workbook(name) #open template
feuilles,names = self.list_paterns(self.document)
self.name_sheet = names[0]
cb1 = ttk.Combobox(self.container,width=30)
cb1['values'] = names
cb1.set(names[0])
cb1.place(x=20,y=100)
cb1.bind('<<ComboboxSelected>>', name_sheet)
cb = ttk.Combobox(self.container, values=("Type1", "Type2", "Type3"),width=10)
cb.set("Type1")
cb.place(x=230,y=100)
cb.bind('<<ComboboxSelected>>', type_sheet)
def generate_code(self,name1):
feuille=self.document.sheet_by_name(name1)
thin_border = Border(left=Side(style='thin'),
right=Side(style='thin'),
top=Side(style='thin'),
bottom=Side(style='thin'))
i=0
cell = " "
wb=load_workbook(name)
for i in wb.get_sheet_names():
wb.remove_sheet(wb.get_sheet_by_name(i))
wb.create_sheet(self.type_sheet)
sheet = wb[self.type_sheet]
for i in range(1,feuille.nrows):
cell = feuille.cell_value(i,0)
S="A"+str(i+1)
if 'MY20_L663_SysRS_FCT-Ass2_' in cell:
y = cell.replace('MY20_L663_SysRS_FCT-Ass2_',' ')
sheet[S].value = y
sheet[S].border = thin_border
if 'MY20_L663_SysRS_FCT-Ass1_' in cell:
y = cell.replace('MY20_L663_SysRS_FCT-Ass1_',' ')
sheet[S].value = y
sheet[S].border = thin_border
if self.type_sheet == "Type1":
sheet["A1"].value = "ID"
sheet["A1"].border = thin_border
sheet["B1"].value = "Responsable"
sheet["B1"].border = thin_border
sheet["C1"].value = "Review"
sheet["C1"].border = thin_border
sheet["D1"].value = "Findings"
sheet["D1"].border = thin_border
sheet["E1"].value = "OK"
sheet["E1"].border = thin_border
sheet["F1"].value = "Comment (Optionnal)"
sheet["F1"].border = thin_border
if self.type_sheet == "Type2":
sheet["A1"].value = "ID"
sheet["A1"].border = thin_border
sheet["B1"].value = "Responsable"
sheet["B1"].border = thin_border
sheet["C1"].value = "Input Status OK"
sheet["C1"].border = thin_border
sheet["D1"].value = "Number of already existing Testcases"
sheet["D1"].border = thin_border
sheet["E1"].value = "Tests created"
sheet["E1"].border = thin_border
sheet["F1"].value = "Number of Tests created"
sheet["F1"].border = thin_border
sheet["G1"].value = "Requirement covered"
sheet["G1"].border = thin_border
sheet["H1"].value = "Output Status OK"
sheet["H1"].border = thin_border
sheet["I1"].value = "Comment (Optionnal)"
sheet["I1"].border = thin_border
if self.type_sheet == "Type3":
sheet["A1"].value = "ID"
sheet["A1"].border = thin_border
sheet["B1"].value = "Responsable"
sheet["B1"].border = thin_border
sheet["C1"].value = "Review"
sheet["C1"].border = thin_border
sheet["D1"].value = "Findings"
sheet["D1"].border = thin_border
sheet["E1"].value = "OK"
sheet["E1"].border = thin_border
sheet["F1"].value = "Output Status OK"
sheet["F1"].border = thin_border
sheet["G1"].value = "Comment (Optionnal)"
sheet["G1"].border = thin_border
for col in range(1,sheet.max_column+1):
for line in range(2,sheet.max_row+1):
sheet.cell(row = line, column = col).border = thin_border
exportFile = asksaveasfilename( defaultextension=".xlsx", filetypes=(("Excel file", "*.xlsx"),("All Files", "*.*") ))
wb.save(exportFile)
messagebox.showinfo("Information", "File successfully generated")
root = tk.Tk()
root.title("ID Extractor")
root.geometry("350x300")
app = Application(root)
app.mainloop()