【问题标题】:Pandas read_excel returning nan for cells having simple formula if excel file is created by program如果 excel 文件是由程序创建的,则 Pandas read_excel 为具有简单公式的单元格返回 nan
【发布时间】:2021-09-17 15:13:58
【问题描述】:

我使用pd.read_excel 读取由openpyxl 创建并从网址下载的excel 文件。

如果单元格值是公式,则解析的数据框将给出nan

# which formula is simply =100-3
       0
0    NaN

我尝试用MS Office手动打开,点击“编辑”按钮,保存,问题解决。

# after saving the excel, problem is solved, e.g. 97
       0
0     97

我想知道是否有以编程方式执行此操作的解决方案?如果不使用 MS Excel 或 win32com 会很棒。谢谢

【问题讨论】:

标签: python pandas openpyxl


【解决方案1】:

没有足够的评论点,但这可能对你有帮助:

stackoverflowanswer

【讨论】:

  • 感谢您的帮助,但我认为有些解决方案适合不同的情况。
【解决方案2】:

在进行了一些搜索后,我发现我的问题可能与(或类似)重复:

并从以下位置找到更多解释:

一些笔记(结论):

  • openpyxl 可以写入但计算 excel 公式,它只是从 MS excel 或其他应用程序(如果可能)使用 data_only=True 参数读取上次计算中的缓存值。
  • 要手动解决这个问题,就像提到的@Orlando 的答案一样,打开 excel 应用程序并保存(将自动计算/生成公式结果)
  • 要以编程方式解决此问题(安装 excel 应用程序),您只需使用 win32com 打开并保存即可。 (见this answer
  • 要以编程方式解决此问题(无需 excel 应用程序),您必须自己或 formulas 等模块从 excel 公式字符串计算结果,然后将计算值设置回单元格(警告:这将删除公式)。如果您还想保留具有默认/缓存值的公式,则应使用XlsxWriter,它可以在具有默认/缓存值的单元格中写入公式。

对我来说,因为我的公式很简单,所以我用evallike:

import openpyxl
wb = openpyxl.load_workbook('./test_formula2.xlsx')
ws = wb.active
ws.cell(2,2).value # '=100-1'
eval(ws.cell(2,2).value[1:]) # slice after '=', e.g. 99

得到计算结果。

【讨论】:

  • 在使用 exec 时必须非常小心,尤其是在使用下载文件时。使用您的方法,很容易制作文件来执行任意代码。例如,在将执行“open('/tmp/malicious_file.txt', 'w').write('malicious code')”的单元格中使用以下文本可以创建任意文件。
  • @mozway 感谢您的通知,虽然excel文件是由我的NAS应用程序创建的,可以信任,我应该更小心地使用eval来运行任意公式。
【解决方案3】:

您可以使用formulas

以下 sn-p 似乎有效:

import formulas
xl_model = formulas.ExcelModel().loads('test_formula.xlsx').finish()
xl_model.calculate()
xl_model.write(dirpath='.')

这将写入一个“TEST_FORMULA.XLSX”(出于某种原因全部大写)文件,其中包含计算值来代替公式。重要的是,这不依赖于 Excel。

如果您需要深入了解,这里是formulas documentation

【讨论】:

  • 正如我在回答中提到的解决方案,您只是举了一个很好的例子!谢谢。
  • 抱歉,我没有阅读所有提供的链接。一个直接的例子更适合未来的用户查看。
猜你喜欢
  • 2020-05-07
  • 2021-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-01
  • 2014-06-03
  • 2018-03-22
  • 1970-01-01
相关资源
最近更新 更多