descriptor 'decode' requires a 'bytes' object but received a 'NoneType'

记录在使用python过程中踩的坑------
使用xlwt库对excel文件进行保存时报错 descriptor 'decode' requires a 'bytes' object but received a 'NoneType'

log:

Traceback (most recent call last):
File "F:/xxxxxx/util/ExcelUtil.py", line 110, in
excel = write_excel("Outbound_Template.xls", 4, 9, "AT2019110912")
File "F:/xxxxxx/util/ExcelUtil.py", line 48, in write_excel
newWb.save(excel_path)
File "F:\Python\lib\site-packages\xlwt\Workbook.py", line 710, in save
doc.save(filename_or_stream, self.get_biff_data())
File "F:\Python\lib\site-packages\xlwt\Workbook.py", line 667, in get_biff_data
before += self.__all_fonts_num_formats_xf_styles_rec()
File "F:\Python\lib\site-packages\xlwt\Workbook.py", line 570, in __all_fonts_num_formats_xf_styles_rec
return self.__styles.get_biff_data()
File "F:\Python\lib\site-packages\xlwt\Style.py", line 185, in get_biff_data
result += self._all_num_formats()
File "F:\Python\lib\site-packages\xlwt\Style.py", line 209, in _all_num_formats
result += NumberFormatRecord(fmtidx, fmtstr).get()
File "F:\Python\lib\site-packages\xlwt\BIFFRecords.py", line 785, in init
ufmtstr = upack2(fmtstr)
File "F:\Python\lib\site-packages\xlwt\UnicodeUtils.py", line 50, in upack2
us = unicode(s, encoding)
TypeError: descriptor 'decode' requires a 'bytes' object but received a 'NoneType'

1.原文件用MS Excel编辑,后执行程序,可以运行
2.原文件用MS Excel编辑,后执行程序,更新后的文件,再用MS Excel编辑,保存,再执行程序,出现上面的错误

我的代码:

# coding:utf-8
def write_excel(file_name, row, col, value, sheet_name="Template"):
    excel_path = Configure.read_config("project_path", "path") + "\\data\\" + file_name
    # formatting_info = True,得以保存之前数据的格式
    old_wb = open_workbook(excel_path, formatting_info=True)
    # 将操作文件对象拷贝,变成可写的workbook对象
    new_wb = copy(old_wb)
    # 获得sheet的对象
    new_ws = new_wb.get_sheet(sheet_name)
    # 写入数据
    new_ws.write(row, col, value)
    # 另存为excel文件,并将文件命名
    new_wb.save(excel_path)

原因:
用xlutils.copy 得到的excel文件,编码格式变了。然后用Office365或WPS去编辑再保存,得到的文件,decode会是None,xlwt save时会出错。(UnicodeUtils.py中的upack2没有考虑到会有None的情况,网上有的解决方式是自己在源码里加多判断None的情况)

源码:

def upack2(s, encoding='ascii'):
    # If not unicode, make it so.
    if isinstance(s, unicode_type):
        us = s
    else:
        us = unicode(s, encoding)
    # Limit is based on number of content characters
    # (not on number of bytes in packed result)
    len_us = len(us)
    if len_us > 32767:
        raise Exception('String longer than 32767 characters')
    try:
        encs = us.encode('latin1')
        # Success here means all chars are in U+0000 to U+00FF
        # inclusive, meaning that we can use "compressed format".
        flag = 0
        n_items = len_us
    except UnicodeEncodeError:
        encs = us.encode('utf_16_le')
        flag = 1
        n_items = len(encs) // 2
        # n_items is the number of "double byte characters" i.e. MS C wchars
        # Can't use len(us).
        # len(u"\U0001D400") -> 1 on a wide-unicode build 
        # and 2 on a narrow-unicode build.
        # We need n_items == 2 in this case.
    return pack('<HB', n_items, flag) + encs

解决方法:用OpenOffice去编辑文件保存就不会有问题

上一篇:11.盛最多水的容器--力扣题解


下一篇:桶排序