excel 即使打开并保存XLXS,表也需要恢复,而不做任何更改

von4xj4u  于 2023-05-23  发布在  其他
关注(0)|答案(1)|浏览(118)

我有一个简单的Excel文件和一个简单的表格:

一旦我用python openpyxl打开它并在我更改标题值后保存它,我得到错误,即表已损坏。
我使用logging用于信息输出,string用于大写字母列表,tkinter用于askopenfilenameopenpyxl用于使用excel。我最初打算使用pandas来处理excel数据,但由于我想在将来保存将在Excel中创建的表格和图表,我没有太多的选择。
代码如下:

class TCA:
    def __init__(self):
        self.path = filedialog.askopenfilename(filetypes=[("Excel files", "*.xlsx; *.xls")], initialdir='.\\')
        self.wb: pxl.Workbook = pxl.load_workbook(self.path, read_only=False)
        self.ws = None

        self.header_names = ['Project', 'TC_all', 'TC_manual', 'TC_automated', 'TC_automateable', 'TC_3rd', 'Ratio']
        self.header_order = {
            'Project': -1,
            'TC_all': -1,
            'TC_manual': -1,
            'TC_automated': -1,
            'TC_automateable': -1,
            'TC_3rd': -1,
            'Ratio': -1
        }
        self.empty_spaces = list(string.ascii_uppercase[:7])

    def load_header_order(self):
        for header in self.header_names:
            for letter in string.ascii_uppercase:
                if header == self.ws[f'{letter}1'].value:
                    self.header_order[header] = letter
                    self.empty_spaces.remove(letter)

        for key, value in self.header_order.items():
            if value == -1:
                self.insert_missing_header(key)

    def insert_missing_header(self, header):
        logging.info(f'There is missing header {header}')
        logging.info(f'Insert in progress')
        self.ws[f'{self.empty_spaces[0]}1'] = f'{header}'
        logging.info(f'Header {header} was inserted into {self.empty_spaces[0]}1')
        self.empty_spaces.__delitem__(0)

    def check_wb(self):
        return 'Preview' in self.wb.sheetnames

    def load_project_list(self):
        self.ws = self.wb['Preview']
        self.load_header_order()

    def exit(self):
        self.wb.save(self.path)

if __name__ == '__main__':
    tca = TCA()

    if not tca.check_wb():
        messagebox.showerror('Crucial error!', 'There is no sheet named "Preview"!\n'
                                               'Due to this exception script cannot proceed!\n'
                                               'If you have renamed the sheet please rename it back...')
        exit(-1)

    tca.load_project_list()
    tca.exit()

我已经测试了很多次,如果excel文件是简单的(没有talbe)代码工程。如果我把文本改为带标题的表格,它就可以工作了。但是一旦我改变了头的值,错误就发生了。

0s7z1bwu

0s7z1bwu1#

我只是找到了问题并解决了它!问题是tables对于headings有自己的column.name,而worksheet有自己的call.value
我只需要改变table.tableColumns[columnIndex].namews[cellIndex].value
结果如下:

class TCA:
    def __init__(self):
        self.path = filedialog.askopenfilename(filetypes=[("Excel files", "*.xlsx; *.xls")], initialdir='.\\')
        self.wb: pxl.Workbook = pxl.load_workbook(self.path, read_only=False)
        self.ws = None
        self.table = None

        self.header_names = ['Project', 'TC_all', 'TC_manual', 'TC_automated', 'TC_automateable', 'TC_3rd', 'Ratio']
        self.header_order = {
            'Project': -1,
            'TC_all': -1,
            'TC_manual': -1,
            'TC_automated': -1,
            'TC_automateable': -1,
            'TC_3rd': -1,
            'Ratio': -1
        }
        self.empty_spaces = list(range(len(self.header_names)))

    def load_header_order(self):
        for header in self.header_names:
            for index, letter in enumerate(string.ascii_uppercase[:7]):
                if header == self.ws[f'{letter}1'].value:
                    self.header_order[header] = index
                    self.empty_spaces.remove(index)
                    break

        for key, value in self.header_order.items():
            if value == -1:
                self.insert_missing_header(key)

    def insert_missing_header(self, header):
        logging.info(f'There is missing header {header}')
        logging.info(f'Insert in progress')
        self.table.tableColumns[self.empty_spaces[0]].name = f'{header}'
        self.ws[f'{chr(65+self.empty_spaces[0])}1'].value = f'{header}'
        logging.info(f'Header {header} was inserted into {chr(65+self.empty_spaces[0])}1')
        self.empty_spaces.__delitem__(0)

    def check_wb(self):
        return 'Preview' in self.wb.sheetnames

    def load_project_list(self):
        self.ws = self.wb['Preview']
        self.table = self.ws.tables['Project_list']
        self.load_header_order()

    def exit(self):
        self.wb.save(self.path)

if __name__ == '__main__':
    tca = TCA()

    if not tca.check_wb():
        messagebox.showerror('Crucial error!', 'There is no sheet named "Preview"!\n'
                                               'Due to this exception script cannot proceed!\n'
                                               'If you renamed the sheet please rename it back...')
        exit(-1)

    tca.load_project_list()
    tca.exit()

相关问题