快速浏览一下openpyxl docs,您可能会发现this page 说
openpyxl 从不计算公式
在继续之前,应该注意可能的重复链接具有与其他模块有关的答案,这些通常是已接受的答案。使用这些模块,您不必实现自己的解析。对于更复杂的系统,这可能是从具有挑战性到几乎不可能的任何地方。
如果您正在做一些非常简单的事情,使用Tokenizer class 并不是很困难。用法:
>>> from openpyxl.formula import Tokenizer
>>> tok = Tokenizer("""=IF($A$1,"then True",MAX(DEFAULT_VAL,'Sheet 2'!B1))""")
>>> print("\n".join("%12s%11s%9s" % (t.value, t.type, t.subtype) for t in tok.items))
IF( FUNC OPEN
$A$1 OPERAND RANGE
, SEP ARG
"then True" OPERAND TEXT
, SEP ARG
MAX( FUNC OPEN
DEFAULT_VAL OPERAND RANGE
, SEP ARG
'Sheet 2'!B1 OPERAND RANGE
) FUNC CLOSE
) FUNC CLOSE
特别注意,一切都是字符串,所以评估公式最好使用eval()
因此,如果您稍微编辑了代码(新的/更改的行标有#),
import openpyxl
from openpyxl import Workbook
from openpyxl.formula import Tokenizer #
wb = openpyxl.load_workbook('test.xlsx')
sheet1 = wb['Sheet1']
C1Formula = sheet1['C1'].value #
C1Token = Tokenizer(C1Formula) #
C1Value = handle_token(sheet1, C1Token) #
print('C1: ', C1Value)
handle_token() 的复杂程度由您决定。 C1: =A1 + B1 和其他二元运算符的几个简单且可能是 hack-y 示例:(这些不适用于 ^,因为 python 将其用于按位 XOR)
def handle_token(sheet, token):
formula = ""
for t in token.items:
if t.type is 'OPERAND':
formula += str(sheet[t.value])
else:
formula += str(t.value)
return eval(formula)
或者,如果您愿意(这可以转换为单线,不推荐)使用生成器:
def handle_token(sheet, token):
parsed = str(sheet[t.value].value) if t.type is 'OPERAND' else t.value for t in token.items
formula = "".join(parsed)
return eval(formula)