openpyxl:保存到文件时将“@”插入到公式中

bob*_*722 6 excel-formula 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')
>>> 
Run Code Online (Sandbox Code Playgroud)

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

=@CONCAT("Week ",TEXT(MID(I1,6,2)+ 1, "##"))
Run Code Online (Sandbox Code Playgroud)

但是,如果我指定“=SUM()”而不是“=CONCAT()”,则它会按预期保存,即不插入“@”。

我正在使用 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>
Run Code Online (Sandbox Code Playgroud)

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

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

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

Dro*_*Av. 8

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

\n\n

一个可以用

\n\n
>>> from openpyxl.utils import FORMULAE\n>>> "CONCAT" in FORMULAE\nFalse\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
>>> ws[\'A1\'] = \'=_xlfn.CONCAT("Week ",TEXT(MID(\' + get_column_letter(9) + \'1,6,2)+ 1, "##"))\n
Run Code Online (Sandbox Code Playgroud)\n\n

文档中也提到了:

\n\n
\n

如果您\xe2\x80\x99 尝试使用\xe2\x80\x99 未知的公式,则可能\n 因为您\xe2\x80\x99\n 使用的公式未包含在初始规范中。此类公式必须带有前缀_xlfn.才能工作。

\n
\n


bob*_*722 0

在 python 代码中显式指定 _xlfn 前缀可以解决该问题:

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

感谢 Dror Av。寻求指导!