python编辑已存在的excel坑: BadZipFile: File is not a zip file

原作者地址:https://www.cnblogs.com/qingyuu/p/10642249.html

背景-原代码如下,期望能自动创建excel,并且可以反复调用编辑:

复制代码
import xlwt,os
from openpyxl.styles import Font, colors

class Write_excel(object):
    """修改excel数据"""

    def __init__(self, filename):
        self.filename = filename

    def write(self, row_n, col_n, value):
        wb=xlwt.Workbook()
        sh=wb.add_sheet('Sheet1',cell_overwrite_ok=True)
        red_style = xlwt.easyxf("font:colour_index red;")
        green_style = xlwt.easyxf("font:colour_index green;")
        # 判断值为错误时添加字体样式
        if value in ['FAIL', 'ERROR'] or col_n == 12:
          sh.write(row_n - 1, col_n - 1, value, red_style)
        elif value == 'PASS':
          ft = Font(color=colors.GREEN)
          sh.write(row_n - 1, col_n - 1, value, green_style)
        else:
           sh.write(row_n - 1, col_n - 1, value)
        wb.save(self.filename)

if __name__ == "__main__":
    wt = Write_excel("test111.xlsx")
    wt.write(1, 1, "FAIL")
    wt.write(2, 1, "PASS")
复制代码

逻辑:使用xlwt模块创建excel,然后编辑内容,保存。

实际结果:仅保留最后一次写入结果。前一次的写入结果未能保存延续下来。

尝试调整方案-解决思路:创建excel前加入判断os.path.exsits(file_name),表格已存在时直接打开编辑,不存在时才创建。

复制代码
def write(i,j,value,filename):
    if not os.path.exists(filename):
        wbk = xlwt.Workbook()
        sheet = wbk.add_sheet('sheet 1')
        sheet.write(i,j,value)
        wbk.save(filename)
    else:
        wb=load_workbook(filename)
        sh =wb['Sheet1']
        sh.cell(i,j).value=value
        wb.save(filename)
write(1,1,'test text','test111.xlsx')
write(2,1,'test text','test111.xlsx')
复制代码

实际结果报错:zipfile.BadZipFile: File is not a zip file,反复尝试过程中发现,我们在代码里创建的excel打开显示受损无法再次编辑,而在路径下手动创建的test111.xlsx就不会有这个问题。百度了下,搜索内容也不少,估计新手小白都碰到过。

为了能反复编辑已存在的excel文件并保存,需要xlwt、xlrd、xlutils组合起来使用,代码如下:

复制代码
import xlwt,os,xlrd
from xlutils.copy import copy

class Do_Excel:
    def __init__(self,filename,sheetname='Sheet1'):
        self.filename=filename
        self.sheetname=sheetname
  
    #读取excel,该部分可忽略
    def excel_read(self,x, y):
        data = xlrd.open_workbook(self.filename)
        table = data.sheet_by_name(self.sheetname)
        return table.cell(x, y).value

    #判断excel文件是否存在,不存在则创建,存在则直接打开编辑
    def excel_create(self):
        if not os.path.exists(self.filename):
            data = xlwt.Workbook()
            table = data.add_sheet(self.sheetname)
            table.write(0, 0, 'id')
            data.save(self.filename)
    
    #综合xlwt/xlrd/xlutils.copy,读写excel
   def write(self,i,j,value): 
     self.excel_create() 
     rb = xlrd.open_workbook(self.filename) 
     wb = copy(rb) #管道作用,通过get_sheet()获取的sheet有write()方法
      ws = wb.get_sheet(0) #1代表是写到第几个工作表里,从0开始算是第一个。
     ws.write(i, j, value) wb.save(self.filename)
Do_Excel('test111.xlsx').write(1,1,'sdcds') 
Do_Excel('test111.xlsx').write(1,2,'ewewe')
复制代码

再尝试多次调用,就都能写入保存成功了。

解决办法二:直接使用openpyxl的Workbook和load_workbook,简单直接

复制代码
rom openpyxl import Workbook,load_workbook
import os

class Do_Excel:
    def __init__(self,filename,sheetname='Sheet1'):
        self.filename=filename
        self.sheetname=sheetname

    def write(self,i,j,value):
        if not os.path.exists(self.filename):
            wb = Workbook()
            sh = wb.create_sheet(self.sheetname)
        else:
            wb = load_workbook(self.filename)
            sh = wb[self.sheetname]
        sh.cell(i,j).value=value
        wb.save(self.filename)

Do_Excel('test222.xlsx').write(1,1,'sdcds')
Do_Excel('test222.xlsx').write(1,2,'change')
Do_Excel('test222.xlsx').write(3,2,'pass')
复制代码