xlrd》操作excel 出現的問題:File "D:\python37\lib\site-packages\xlrd\formula.py", line 1150, in evaluate_name_formula assert len(tgtobj.stack) == 1
xlrd》操作excel 出現的問題
報錯如下:
D:\python37\python.exe D:/testWang/waimai/tools/get_excelData.py
*** formula/tFunc unknown FuncID:186
*** formula/tFunc unknown FuncID:186
*** formula/tFunc unknown FuncID:186
*** formula/tFunc unknown FuncID:186
*** formula/tFunc unknown FuncID:186
*** formula/tFunc unknown FuncID:186
Traceback (most recent call last):
File "D:/testWang/waimai/tools/get_excelData.py", line 42, in <module>
print(get_excelData('登入模組', 2, 7))
File "D:/testWang/waimai/tools/get_excelData.py", line 18, in get_excelData
workBook = xlrd.open_workbook(excelDir, formatting_info=True)
File "D:\python37\lib\site-packages\xlrd\__init__.py", line 157, in open_workbook
ragged_rows=ragged_rows,
File "D:\python37\lib\site-packages\xlrd\book.py", line 117, in open_workbook_xls
bk.parse_globals()
File "D:\python37\lib\site-packages\xlrd\book.py", line 1245, in parse_globals
self.names_epilogue()
File "D:\python37\lib\site-packages\xlrd\book.py", line 1043, in names_epilogue
evaluate_name_formula(self, nobj, namex, blah=blah)
File "D:\python37\lib\site-packages\xlrd\formula.py", line 1150, in evaluate_name_formula
assert len(tgtobj.stack) == 1
AssertionError
Process finished with exit code 1
問題現象:
python指令碼在呼叫xlrd模組解析excel檔案時,提示如下錯誤:
*** formula/tFunc unknown FuncID:186
進而導致整個指令碼崩潰。
原因分析:
xlrd模組在解析excel檔案時會嘗試解析excel中的函式,這些函式被定義在一個字典
而當前xlrd對excel函式的支援並不全,比如index:186的就不支援;
遇到這種不支援的函式,xlrd會assert異常,終止解析;
其實這種做法無可厚非,遇到未知的情況,在不能保證正確的情況下終止解析,看起來是最好的;
但是,在有些情況下,我們還是希望能夠選擇忽略掉這個錯誤接著解析的,但是xlrd沒有給我們這個選擇。
解決方案:
思路:忽略異常,繼續解析檔案;
思路一: 讓assert無效。
我知道c++在release版中assert都是無效的,但是python中貌似做不到。
我嘗試過把指令碼編譯成pyc後執行,但仍會assert的。
思路二: 修改xlrd
既然問題出在xlrd上,那麼最直接的辦法就是修改xlrd;這裡有兩種方案:
一、方案一:
參考網上的方法,對未知的excel函式,假裝知道——在xlrd的字典中,新增FuncID:186,讓xlrd認為支援這個函式,不再報錯:
/usr/local/lib/python3.4/site-packages/xlrd-1.0.0-py3.4.egg/xlrd/formula.py:240
- 184: ('FACT', 1, 1, 0x02, 1, 'V', 'V'),
- + 186: ('HACKED', 1, 1, 0x02, 1, 'V', 'V'),
- 189: ('DPRODUCT', 3, 3, 0x02, 3, 'V', 'RRR'),
二、方案二:
與方案一思路一致,刪除assert,讓程式繼續進行下去;
/usr/local/lib/python3.4/site-packages/xlrd-1.0.0-py3.4.egg/xlrd/formula.py:1307
- else:
- # assert len(tgtobj.stack) == 1
- res = copy.deepcopy(tgtobj.stack[0])
優劣:
方案一:修改後影響未知,xlrd最終會怎麼處理186這個id我並不清楚;
方案二:相對安全,但我們喪失了提前得知指令碼有問題的優勢;
思路三: 使用期他的excel庫解析;
逃避方案:xlwingsble/, openpyxl/en/latest/, pandas, win32com-excel-mini-cookbook/, xlsxwriter/, DataNitro
結論
綜合考慮,目前我採用的是第二個思路的方案二。
參考資料:
https://stackoverflow.com/questions/29971186/python-xlrd-error-formula-tfunc-unknown-funcid186