12

我制作了一个脚本,它打开一个 .xls 文件,在其中写入一些新值,然后保存文件。

稍后,脚本再次打开它,并希望在某些包含公式的单元格中找到答案。

如果我用 openpyxl 调用该单元格,我会得到公式(即:)"=A1*B1"。如果我激活data_only,我什么也得不到。

有没有办法让 Python 计算 .xls 文件?(或者我应该尝试 PyXll 吗?)

4

6 回答 6

7

我意识到这个问题很老,但是我遇到了同样的问题并且广泛的搜索没有产生答案。

解决方案实际上非常简单,因此我将在此处发布以供后代使用。

假设您有一个用 .xlsx 修改过的 xlsx 文件openpyxl。正如查理克拉克所说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。

于 2017-10-05T16:56:29.580 回答
6

实际上有一个项目采用 Excel 公式并使用 Python 评估它们: PycelPycel 使用 Excel 本身(通过 COM)来提取公式,因此在您的情况下,您将跳过该部分。 该项目可能有一些有用的东西可以使用,但我不能保证它的成熟度或完整性。 它并不是真正为大众开发的

还有一个名为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 执行此操作的简单方法。

于 2014-03-18T23:07:46.397 回答
6

公式模块对我有用。详情请参考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
于 2019-09-12T01:52:42.803 回答
2

我遇到了同样的问题,经过一段时间的研究,我最终使用了 pyoo ( https://pypi.org/project/pyoo/ ),它适用于 openoffice/libreoffice,因此可在所有平台上使用,并且更直接,因为可以本地通信并且不需要保存/关闭文件。我尝试了其他几个库,但发现了以下问题

  • xlswings:仅当您安装了 Excel 和 Windows/MacOS 时才有效,所以我无法评估
  • koala : networkx 2.4 更新后好像坏了。
  • openpyxl:正如其他人所指出的,它无法计算公式,所以我正在考虑将它与 pycel 结合以获取值。我最终没有尝试,因为我找到了 pyoo。Openpyxl+pycel 目前可能无法工作,因为 pycel 也依赖于 networkx 库。
于 2019-12-09T02:20:09.457 回答
1

不,openpyxl永远不会有。我认为有一个 Python 库旨在为您可以使用的这种公式实现一个引擎。

于 2014-03-18T17:07:35.877 回答
1

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
于 2020-05-04T04:55:26.707 回答