記錄在使用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去編輯文件保存就不會有問題