Openpyxl:保存到文件时'@'插入公式



当我将以下公式添加到单元格中时,该单元格的值在打印到控制台时看起来很好。然而,在我保存文件后,公式在"="后面插入了"@"(为了简单起见,我从控制台提供输出(:

>>> from openpyxl import Workbook
>>> wb = Workbook()
>>> ws = wb.active
>>> ws['A1'] = '=CONCAT("Week ",TEXT(MID(' + get_column_letter(9) + '1,6,2)+ 1, "##"))'
>>> ws['A1'].value
'=CONCAT("Week ",TEXT(MID(I1,6,2)+ 1, "##"))'
>>> wb.save('formula.xlsx')
>>> 

在"formula.xlsx"文件中,公式如下所示:

=@CONCAT("Week ",TEXT(MID(I1,6,2)+ 1, "##"))

但是,例如,如果我指定的不是'=CONCAT(('而是'=SUM((',则会按预期保存,即不插入'@'。

我使用的是openpyxl 3.0.3和Python 3.8。

非常感谢

--------日期--------

我已经研究了"formula.xlsx"的XML代码;但在此之前,我在Excel中打开了它,将单元格A1复制到单元格D1中,并从单元格D1中的公式中删除了"@",之后D1开始显示正确的值,而A1仍然显示"#NAME?"错误

因此,在我对单元格D1进行更改后,表单的XML代码显示如下:

<row r="1" spans="1:9" x14ac:dyDescent="0.45">
<c r="A1" t="e"><f ca="1">_xludf.CONCAT("Week ",TEXT(MID(I1,6,2)+ 1, "##"))</f><v>#NAME?</v></c>
<c r="D1" t="str"><f>_xlfn.CONCAT("Week ",TEXT(MID(I1,6,2)+ 1, "##"))</f><v>Week 68</v></c>
<c r="I1"><v>12345678</v></c>
</row>

openpyxl在上面的单元格A1中为CONCAT使用的_xludf前缀被描述为上的"用户定义函数"https://learn.microsoft.com/en-us/office/client-developer/excel/xludf.

这是否意味着库没有将CONCAT识别为标准Excel函数,因此使用了_xludf而不是_xlfn?

-----更新结束---

根据openpyxl文档中的指定,只需插入公式名称即可使用已知公式。

可以使用

>>> from openpyxl.utils import FORMULAE
>>> "CONCAT" in FORMULAE
False

检查openpyxl中的公式是否为已知公式。如果公式不是,您需要在公式名称之前添加_xlfn.,如下所示:

>>> ws['A1'] = '=_xlfn.CONCAT("Week ",TEXT(MID(' + get_column_letter(9) + '1,6,2)+ 1, "##"))

文件中也提到:

如果你试图使用一个未知的公式,这可能是因为您使用的公式未包含在初始规格这样的公式必须以_xlfn.为前缀才能工作。

我在使用西班牙语公式时遇到了同样的问题(我来自阿根廷(。当我试图分配类似于"=SUMA(A1:A20(";对于细胞来说=@SUMA(A1:A20(";。

我试过了。解决方案,但现在它只是以"@_xlfn。SUMA(A1:A20(";

如果我找到答案,我会把它贴在这里。

已解决如果您使用的是非英文版本的Excel,您仍然需要为单元格指定函数的英文名称,例如"=SUM(A1:A20(";之后,当您检查工作表中单元格的内容时,它将更改为正确的语言,在这种情况下为西班牙语"=SUMA(A1:A20(";

Caveat:我只在西班牙语版本中检查过,但我很确定它适用于所有人。

此外:如果使用另一组字符作为分隔符,例如逗号(,(而不是小数点(.(,则在为单元格分配公式时仍需要使用点,例如"=E8*0.5〃;。当你检查单元格时,你会看到一个逗号。在该字符串中使用逗号将导致打开xlsx文件时出现损坏的文件错误。

在我的例子中,我试图放入=ARRED公式,字符@=@ARRED一样出现在Excel文件中。

ARRED是一个巴西葡萄牙语前缀,不被识别,所以我用ROUND代替了它,效果很好。

测试:

from openpyxl.utils import FORMULAE
"ARRED" in FORMULAE
False
"ROUND" in FORMULAE
True

在python代码中显式指定_xlfn前缀可以修复问题:

>>> ws['A1'] = '=_xlfn.CONCAT("Week ",TEXT(MID(' + get_column_letter(9) + '1,6,2)+ 1, "##"))'

感谢Dror Av。寻求指导!

最新更新