AttributeError:'NoneType'对象没有属性'read'

时间:2019-02-26 09:01:42

标签: python python-3.x openpyxl

我正在尝试使用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'

任何人都可以解决这个问题

2 个答案:

答案 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()