python xlrd error: *** formula/tFunc unknown FuncID:186

问题现象

python脚本在调用xlrd模块解析excel文件时,提示如下错误:

*** formula/tFunc unknown FuncID:186
 进而导致整个脚本崩溃。


原因分析

xlrd模块在解析excel文件时会尝试解析excel中的函数,这些函数被定义在一个字典,形式如下:

func_defs = {
    # index: (name, min#args, max#args, flags, #known_args, return_type, kargs)
    0  : ('COUNT',            0, 30, 0x04,  1, 'V', 'R'),
    1  : ('IF',               2,  3, 0x04,  3, 'V', 'VRR'),
    2  : ('ISNA',             1,  1, 0x02,  1, 'V', 'V'),
    3  : ('ISERROR',          1,  1, 0x02,  1, 'V', 'V'),
……
    183: ('PRODUCT',          0, 30, 0x04,  1, 'V', 'R'),
    184: ('FACT',             1,  1, 0x02,  1, 'V', 'V'),
    189: ('DPRODUCT',         3,  3, 0x02,  3, 'V', 'RRR'),
    190: ('ISNONTEXT',        1,  1, 0x02,  1, 'V', 'V'),
……
}

而当前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库解析;

 逃避方案: 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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值