我编写了一个脚本,打开一个 .xls 文件,在其中写入一些新的数值,然后保存该文件。
稍后,脚本再次打开该文件,并想要在某些包含公式的单元格中找到答案。
如果使用 openpyxl 调用该单元格,会得到公式(例如:"=A1*B1"
)。
而如果激活 data_only
,则什么也不会得到。
有没有办法让 Python 计算 .xls 文件?(或者应该尝试 PyXll?)
openpyxl
修改过的xlsx文件。如Charlie Clark所提到的,openpyxl
不会计算公式,但是如果您在excel中打开该文件,则公式将自动计算。因此,您所需要做的就是打开文件,然后使用excel保存它。win32com
模块。import win32com.client as win32
excel = win32.gencache.EnsureDispatch('Excel.Application')
workbook = excel.Workbooks.Open(r'absolute/path/to/your/file')
# this must be the absolute path (r'C:/abc/def/ghi')
workbook.Save()
workbook.Close()
excel.Quit()
就是这样。我看到了使用Pycel或Koala的建议,但如果你只需要告诉Excel打开和保存文件,那似乎有点过度杀伤力。
当然,这个解决方案仅适用于Windows。
实际上有一个项目可以使用Python来评估Excel公式:Pycel。Pycel使用Excel本身(通过COM)来提取公式,因此在您的情况下,您可以跳过该部分。该项目可能有一些有用的东西,但我不能保证其成熟度或完整性。它实际上并不是为普通大众开发的。
还有一个名为Koala的新项目,它建立在Pycel和OpenPyXL的基础之上。
如果您无法使用Excel,但是可以在Python代码中计算公式的结果,则另一种方法是将值和公式都写入单元格中(这样当您读取文件时,只需提取值,而不必担心公式)。截至本文撰写时,我还没有找到在OpenPyXL中实现它的方法,但XlsxWriter可以实现。来自文档:最后,如果您有Excel,则可能最简单可靠的方法是自动打开并在Excel中重新保存文件(以便它会为您计算和编写公式的值)。xlwings是从Windows或Mac轻松完成此操作的方法。
这个公式模块对我很有用。详细信息请参见https://pypi.org/project/formulas/
from openpyxl import load_workbook
import formulas
#The variable spreadsheet provides the full path with filename to the excel spreadsheet with unevaluated formulae
fpath = path.basename(spreadsheet)
dirname = path.dirname(spreadsheet)
xl_model = formulas.ExcelModel().loads(fpath).finish()
xl_model.calculate()
xl_model.write(dirpath=dirname)
#Use openpyxl to open the updated excel spreadsheet now
wb = load_workbook(filename=spreadsheet,data_only=True)
ws = wb.active
openpyxl
中也永远不会有。我认为有一个Python库声称可以实现这些公式的引擎,你可以使用它。xlcalculator可以完成这个任务。https://github.com/bradbase/xlcalculator
from xlcalculator import ModelCompiler
from xlcalculator import Model
from xlcalculator import Evaluator
filename = r'use_case_01.xlsm'
compiler = ModelCompiler()
new_model = compiler.read_and_parse_archive(filename)
evaluator = Evaluator(new_model)
# First!A2
# value is 0.1
#
# Fourth!A2
# formula is =SUM(First!A2+1)
val1 = evaluator.evaluate('Fourth!A2')
print("value 'evaluated' for Fourth!A2:", val1)
evaluator.set_cell_value('First!A2', 88)
# now First!A2 value is 88
val2 = evaluator.evaluate('Fourth!A2')
print("New value for Fourth!A2 is", val2)
file_name use_case_01.xlsm ignore_sheets []
value 'evaluated' for Fourth!A2: 1.1
New value for Fourth!A2 is 89