Python 3.4:无法从Excel公式中读取值

时间:2017-01-17 03:35:37

标签: python excel openpyxl

我尝试用Python 3.4获取Excel文件的单元格C1的值。 单元C1是公式:= A1 + B1。 注意:A1和B1值正在变化,因此C1中的返回值必须相应地自动更改

在Python 3.4中,我使用以下代码:

import openpyxl
from openpyxl import Workbook

wb = openpyxl.load_workbook('test.xlsx')
sheet1 = wb['Sheet1']
C1Value = sheet1['C1'].value
print('C1: ', C1Value)

==

运行python程序时,我获得: C1:= A1 + B1

我想要获得的是:

A1 = 1,B1 = 2然后 C1:3(而不是C1:= A1 + B1)

和 A1 = 10,B1 = 20然后自动 C1:30(而不是C1:= A1 + B1)

任何帮助,想法将不胜感激。感谢。

1 个答案:

答案 0 :(得分:0)

快速查看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)