openpyxl: '@' is inserted to formula when saving to file

北战南征 提交于 2021-02-10 22:42:19

问题


When I add the following formula to a cell, the cell's value looks good when printed to the console. However, after I save the file, the formula has '@' inserted right after the '=' (for simplicity, I am providing the output from the console):

>>> 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')
>>> 

In the 'formula.xlsx' file, the formula looks like this:

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

If, however, instead of '=CONCAT()' I specify '=SUM()', for example, it is saved as expected, i.e. without the '@' inserted.

I am using openpyxl 3.0.3 and Python 3.8.

Many thanks

-------- Udate --------

I have looked into the XML code of 'formula.xlsx'; but before doing that, I opened it in Excel, copied cell A1 into cell D1, and deleted '@' from the formula in cell D1, after which D1 started showing the correct value while A1 still showed the '#NAME?' error.

So, after my changes in cell D1, the XML code for the sheet showed the following:

<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>

The _xludf prefix used by openpyxl for CONCAT in cell A1 above is described as "User Defined Function" on https://docs.microsoft.com/en-us/office/client-developer/excel/xludf.

Could it mean that the library did not recognise CONCAT as a standard Excel function, and therefore used _xludf instead of _xlfn for it?

----- End of update ---


回答1:


Specifying _xlfn prefix explicitly in the python code fixes the problem:

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

Thanks goes to Dror Av. for guidance!




回答2:


As specified in the openpyxl documentation known formulas are used just by inserting the formula name.

One can use

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

To check if the formula is a known one in openpyxl. If the formula isn't you need to add _xlfn. just before the formula name, like so:

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

It is also mentioned in the documentation:

If you’re trying to use a formula that isn’t known this could be because you’re using a formula that was not included in the initial specification. Such formulae must be prefixed with _xlfn. to work.



来源:https://stackoverflow.com/questions/61705150/openpyxl-is-inserted-to-formula-when-saving-to-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!