【问题标题】:Python 3.4: Unable to read value from Excel FormulaPython 3.4:无法从 Excel 公式中读取值
【发布时间】:2017-01-17 03:35:37
【问题描述】:

我尝试使用 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)

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

【问题讨论】:

标签: python excel openpyxl


【解决方案1】:

快速浏览一下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)

【讨论】:

  • 它的工作原理就像一个魅力:wb = openpyxl.load_workbook('test.xlsx', data_only=True)
【解决方案2】:

调用load_workbook时需要加data_only=True,如下:

wb = openpyxl.load_workbook('test.xlsx', data_only=True)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多