openpyxl
仅支持对单元格中嵌入的公式进行有限的解析。那个openpyxl.formula
包包含一个Tokenizer
类,用于将公式分解为其组成的标记。用法如下:
>>> 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
如上所示,Tokenizer
类有三个有趣的属性:
-
.value
:生成此标记的公式的子字符串 -
.type
:表示的令牌类型。可以是-
Token.LITERAL
:如果单元格不包含公式,则其值由单个LITERAL
标记表示。 -
Token.OPERAND
:Excel公式中任何值的通用术语。(有关详细信息,请参阅下面的.subtype
)。 -
Token.FUNC
:函数调用以参数为标记被分解,例如公示SUM(a,b)
将分解为SUM(
,参数,然后是闭包即)
。函数名和左括号一起构成一个FUNC
标记,匹配的括号构成另一个FUNC
标记。 -
Token.ARRAY
:数组文本(括在大括号之间)分别获取两个“Array”标记,一个用于开头的“{”,另一个用于结尾的“}”。 -
Token.PAREN
:用于分组子表达式(而不是表示函数调用)时,括号被标记为“PAREN”标记(一个高位字符)。 -
Token.SEP
:这些标记是从逗号,
或位号;
创建的。当逗号用于分离函数参数(例如SUM(a,b)
)或用于分离数组元素(例如{a,b}
)时,它们会创建SEP
标记。(它们还有另一个用途,作为连接范围的固定运算符)。分号总是用来分隔数组文本中的行,因此总是创建“SEP”标记。 -
Token.OP_PRE
:指定前缀一元运算符。它的值总是+
或-
-
Token.OP
:指定为中缀二元运算符。可能的值是>=
,<=
,<>
,=
,>
,<
,*
,/
,+
,-
,^
, 或者&
。 -
Token.OP_POST
:指定后缀一元运算符。它的值始终是%
。 -
Token.WSPACE
:为遇到的任何空白创建。不管找到多少空白,它的值始终是一个空格。
-
-
.subtype
:上面的一些令牌类型使用该子类型提供有关该令牌的附加信息。可能的子类型有:-
Token.TEXT
,Token.NUMBER
,Token.LOGICAL
,Token.ERROR
,Token.RANGE
:这些子类型描述公式中各种形式的OPERAND
。LOGICAL
是TRUE
或FALSE
,RANGE
是命名范围或对另一个范围的直接引用。TEXT
,NUMBER
,和ERROR
都是公式中的文字值 -
Token.OPEN
以及Token.CLOSE
:这两个子类型由PAREN
、FUNC
和ARRAY
使用,用于描述标记是正在打开新子表达式还是正在关闭它。 -
Token.ARG
和Token.ROW
:由SEP
标记使用,用于在逗号和分号之间进行区分。逗号生成子类型ARG
的标记,而分号生成子类型ROW
的标记
-
将公式从一个位置转换到另一个位置¶
在数学意义上,可以使用:class:openpyxl.formulas.translate.Translator
类。例如,有一个单元格区域“B2:E7”,其中“F”列中每行的总和为:
>>> from openpyxl.formula.translate import Translator
>>> ws['F2'] = "=SUM(B2:E2)"
>>> # move the formula one colum to the right
>>> ws['G2'] = Translator("=SUM(B2:E2)", origin="F2").translate_formula("G2")
>>> ws['G2'].value
'=SUM(C2:F2)'
注意,“A1”单元格只引用,不支持已定义的名称。