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