不打开Excel表计算(openpyxl或xlwt)

17 投票
6 回答
35593 浏览
提问于 2025-04-17 22:38

我写了一个脚本,可以打开一个 .xls 文件,在里面写入一些新值,然后保存这个文件。

之后,这个脚本又打开这个文件,想要找到一些包含公式的单元格里的结果。

如果我用 openpyxl 来调用那个单元格,我得到的是公式,比如说:"=A1*B1"。而如果我开启 data_only,我什么也得不到。

有没有办法让 Python 计算这个 .xls 文件里的内容呢?(或者我应该试试 PyXll 吗?)

6 个回答

2

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
3

我遇到了同样的问题,经过一段时间的研究,我最终选择了使用 pyoo(https://pypi.org/project/pyoo/),这个库是专门为 OpenOffice 和 LibreOffice 设计的,所以在所有平台上都能用,而且使用起来更简单,因为它可以直接沟通,不需要先保存或关闭文件。我尝试了其他几个库,但发现了以下问题:

  • xlswings:这个库只能在安装了 Excel 的 Windows 或 MacOS 上使用,所以我没法测试。
  • koala:看起来在更新了 networkx 2.4 之后就坏掉了。
  • openpyxl:正如其他人提到的,它不能计算公式,所以我考虑把它和 pycel 结合使用来获取值。但最后我没有尝试,因为我找到了 pyoo。现在 openpyxl 和 pycel 可能也不太能一起用,因为 pycel 也依赖于 networkx 库。
7

这个公式模块对我来说很好用。想了解更多细节,可以参考这个链接: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
8

我知道这个问题已经很久了,但我遇到了同样的问题,找了很久也没找到答案。

其实解决办法很简单,所以我在这里分享一下,以便后人参考。

假设你有一个用 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 系统。

8

其实有一个项目可以用Python来处理Excel公式,这个项目叫做PycelPycel是通过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上使用。

撰写回答