不打开Excel表计算(openpyxl或xlwt)
我写了一个脚本,可以打开一个 .xls 文件,在里面写入一些新值,然后保存这个文件。
之后,这个脚本又打开这个文件,想要找到一些包含公式的单元格里的结果。
如果我用 openpyxl 来调用那个单元格,我得到的是公式,比如说:"=A1*B1"
。而如果我开启 data_only
,我什么也得不到。
有没有办法让 Python 计算这个 .xls 文件里的内容呢?(或者我应该试试 PyXll 吗?)
6 个回答
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
我遇到了同样的问题,经过一段时间的研究,我最终选择了使用 pyoo(https://pypi.org/project/pyoo/),这个库是专门为 OpenOffice 和 LibreOffice 设计的,所以在所有平台上都能用,而且使用起来更简单,因为它可以直接沟通,不需要先保存或关闭文件。我尝试了其他几个库,但发现了以下问题:
- xlswings:这个库只能在安装了 Excel 的 Windows 或 MacOS 上使用,所以我没法测试。
- koala:看起来在更新了 networkx 2.4 之后就坏掉了。
- openpyxl:正如其他人提到的,它不能计算公式,所以我考虑把它和 pycel 结合使用来获取值。但最后我没有尝试,因为我找到了 pyoo。现在 openpyxl 和 pycel 可能也不太能一起用,因为 pycel 也依赖于 networkx 库。
这个公式模块对我来说很好用。想了解更多细节,可以参考这个链接: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
修改过的 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本身来提取公式的,所以在你的情况下可以跳过这部分。这个项目可能有一些有用的功能可以用,但我不能保证它的成熟度或完整性。它并不是专门为大众开发的。
还有一个更新的项目叫做Koala,它结合了Pycel和OpenPyXL的功能。
如果你不能使用Excel,但你可以在自己的Python代码中计算公式的结果,另一种方法是把值和公式都写入一个单元格(这样当你读取文件时,只需要提取值,而不需要担心公式)。截至目前,我还没有找到在OpenPyXL中实现这个的方法,但XlsxWriter可以做到。根据文档:
XlsxWriter不会计算公式的值,而是将0作为公式的结果存储。然后它在XLSX文件中设置一个全局标志,表示当文件打开时,所有公式和函数都应该重新计算。这是Excel文档中推荐的方法,通常在电子表格应用程序中效果很好。然而,一些没有计算公式功能的应用程序,比如Excel Viewer或某些移动应用,只会显示0的结果。
如果需要,也可以使用选项值参数来指定公式的计算结果。这在处理一些不计算公式值的非Excel应用程序时偶尔是必要的。计算值会被添加到参数列表的末尾:
worksheet.write_formula('A1', '=2+2', num_format, 4)
使用这种方法,当你需要读取值时,可以使用OpenPyXL的data_only
选项。(对于其他阅读这个回答的人来说:如果你使用xlrd,那么只会得到值。)
最后,如果你确实有Excel,那么最简单可靠的方法就是自动打开并重新保存你的文件,这样Excel就会为你计算并写入公式的值。xlwings是一个很简单的方法,可以在Windows或Mac上使用。