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

  1.  
    184: ('FACT', 1, 1, 0x02, 1, 'V', 'V'),
  2.  
    + 186: ('HACKED', 1, 1, 0x02, 1, 'V', 'V'),
  3.  
    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

  1.  
    else:
  2.  
    # assert len(tgtobj.stack) == 1
  3.  
    res = copy.deepcopy(tgtobj.stack[ 0])

 

優劣:

方案一:修改后影響未知,xlrd最終會怎么處理186這個id我並不清楚;

方案二:相對安全,但我們喪失了提前得知腳本有問題的優勢;

思路三: 使用期他的excel庫解析;

 逃避方案: xlwings, openpyxl, pandas, win32com, xlsxwriter, DataNitro

 

結論

綜合考慮,目前我采用的是第二個思路的方案二。

 

參考資料:

https://stackoverflow.com/questions/29971186/python-xlrd-error-formula-tfunc-unknown-funcid186

https://github.com/python-excel/xlrd/issues/154

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM