在Python代码中解析和编译Excel公式和工作簿。
项目描述
什么是formulas?
formulas 实现了一个Excel公式的解释器,可以解析和编译Excel公式表达式。
此外,它可以将Excel工作簿编译成Python代码并执行,无需使用Excel COM服务器。因此,无需Excel。
安装
使用(具有root权限)安装它
$ pip install formulas
或者下载最新的Git版本并使用(需要root权限)
$ python setup.py install
安装额外功能
安装以下额外功能可以启用一些附加功能
excel:启用将Excel工作簿编译成Python并使用ExcelModel执行。
plot:启用绘制公式AST和Excel模型。
要安装公式和所有额外功能,请执行以下操作
$ pip install formulas[all]
开发版本
为了帮助测试和开发公式,您可以安装开发版本
$ pip install https://github.com/vinci1it2000/formulas/archive/dev.zip
基本示例
以下部分将展示如何
解析Excel公式;
加载、编译和执行Excel工作簿;
从Excel工作簿中提取子模型;
添加自定义函数。
解析公式
以下是一个如何解析和执行Excel公式的示例
>>> import formulas >>> func = formulas.Parser().ast('=(1 + 1) + B3 / A2')[1].compile()
为了可视化公式模型并获取输入顺序,您可以执行以下操作
>>> list(func.inputs) ['A2', 'B3'] >>> func.plot(view=False) # Set view=True to plot in the default browser. SiteMap([(=((1 + 1) + (B3 / A2)), SiteMap())])
[图形]
最后,执行公式并绘制工作流程
>>> func(1, 5) Array(7.0, dtype=object) >>> func.plot(workflow=True, view=False) # Set view=True to plot in the default browser. SiteMap([(=((1 + 1) + (B3 / A2)), SiteMap())])
[图形]
Excel工作簿
以下是一个如何加载、计算和写入Excel工作簿的示例
>>> import formulas >>> fpath, dir_output = 'excel.xlsx', 'output' >>> xl_model = formulas.ExcelModel().loads(fpath).finish() >>> xl_model.calculate() Solution(...) >>> xl_model.write(dirpath=dir_output) {'EXCEL.XLSX': {Book: <openpyxl.workbook.workbook.Workbook ...>}}
- 提示:如果您有或可能存在循环引用,请在finish方法中添加circular=True。
circular=True到finish方法。
绘制描述Excel单元格之间关系的依赖关系图
>>> dsp = xl_model.dsp >>> dsp.plot(view=False) # Set view=True to plot in the default browser. SiteMap([(ExcelModel, SiteMap(...))])
[图形]
要覆盖由Excel文件定义的默认输入,或将某些值强加给特定单元格
>>> xl_model.calculate( ... inputs={ ... "'[excel.xlsx]'!INPUT_A": 3, # To overwrite the default value. ... "'[excel.xlsx]DATA'!B3": 1 # To impose a value to B3 cell. ... }, ... outputs=[ ... "'[excel.xlsx]DATA'!C2", "'[excel.xlsx]DATA'!C4" ... ] # To define the outputs that you want to calculate. ... ) Solution([("'[excel.xlsx]'!INPUT_A", <Ranges>('[excel.xlsx]DATA'!A2)=[[3]]), ("'[excel.xlsx]DATA'!B3", <Ranges>('[excel.xlsx]DATA'!B3)=[[1]]), ("'[excel.xlsx]DATA'!A2", <Ranges>('[excel.xlsx]DATA'!A2)=[[3]]), ("'[excel.xlsx]DATA'!A3", <Ranges>('[excel.xlsx]DATA'!A3)=[[6]]), ("'[excel.xlsx]DATA'!D2", <Ranges>('[excel.xlsx]DATA'!D2)=[[1]]), ("'[excel.xlsx]'!INPUT_B", <Ranges>('[excel.xlsx]DATA'!A3)=[[6]]), ("'[excel.xlsx]DATA'!B2", <Ranges>('[excel.xlsx]DATA'!B2)=[[9.0]]), ("'[excel.xlsx]DATA'!D3", <Ranges>('[excel.xlsx]DATA'!D3)=[[2.0]]), ("'[excel.xlsx]DATA'!C2", <Ranges>('[excel.xlsx]DATA'!C2)=[[10.0]]), ("'[excel.xlsx]DATA'!D4", <Ranges>('[excel.xlsx]DATA'!D4)=[[3.0]]), ("'[excel.xlsx]DATA'!C4", <Ranges>('[excel.xlsx]DATA'!C4)=[[4.0]])])
要从一个具有固定输入和输出的Excel模型中构建一个单函数,您可以使用ExcelModel的compile方法,该方法返回一个DispatchPipe。这是一个输入和输出由数据节点ID(即单元格引用)定义的函数。
>>> func = xl_model.compile( ... inputs=[ ... "'[excel.xlsx]'!INPUT_A", # First argument of the function. ... "'[excel.xlsx]DATA'!B3" # Second argument of the function. ... ], # To define function inputs. ... outputs=[ ... "'[excel.xlsx]DATA'!C2", "'[excel.xlsx]DATA'!C4" ... ] # To define function outputs. ... ) >>> func <schedula.utils.dsp.DispatchPipe object at ...> >>> [v.value[0, 0] for v in func(3, 1)] # To retrieve the data. [10.0, 4.0] >>> func.plot(view=False) # Set view=True to plot in the default browser. SiteMap([(ExcelModel, SiteMap(...))])
[图形]
或者,要加载从输出单元格开始的Excel模型的部分,您可以使用ExcelModel的from_ranges方法。
>>> xl = formulas.ExcelModel().from_ranges( ... "'[%s]DATA'!C2:D2" % fpath, # Output range. ... "'[%s]DATA'!B4" % fpath, # Output cell. ... ) >>> dsp = xl.dsp >>> sorted(dsp.data_nodes) ["'[excel.xlsx]'!INPUT_A", "'[excel.xlsx]'!INPUT_B", "'[excel.xlsx]'!INPUT_C", "'[excel.xlsx]DATA'!A2", "'[excel.xlsx]DATA'!A3", "'[excel.xlsx]DATA'!A3:A4", "'[excel.xlsx]DATA'!A4", "'[excel.xlsx]DATA'!B2", "'[excel.xlsx]DATA'!B3", "'[excel.xlsx]DATA'!B4", "'[excel.xlsx]DATA'!C2", "'[excel.xlsx]DATA'!D2"]
[图形]
JSON导出/导入
ExcelModel可以导出/导入为可读的JSON格式。此功能的原因是拥有一种易于维护的格式(例如,使用版本控制程序如git)。以下是如何导出/导入ExcelModel到/从JSON的示例。
>>> import json >>> xl_dict = xl_model.to_dict() # To JSON-able dict. >>> xl_dict # Exported format. { "'[excel.xlsx]DATA'!A1": "inputs", "'[excel.xlsx]DATA'!B1": "Intermediate", "'[excel.xlsx]DATA'!C1": "outputs", "'[excel.xlsx]DATA'!D1": "defaults", "'[excel.xlsx]DATA'!A2": 2, "'[excel.xlsx]DATA'!D2": 1, "'[excel.xlsx]DATA'!A3": 6, "'[excel.xlsx]DATA'!A4": 5, "'[excel.xlsx]DATA'!B2": "=('[excel.xlsx]DATA'!A2 + '[excel.xlsx]DATA'!A3)", "'[excel.xlsx]DATA'!C2": "=(('[excel.xlsx]DATA'!B2 / '[excel.xlsx]DATA'!B3) + '[excel.xlsx]DATA'!D2)", "'[excel.xlsx]DATA'!B3": "=('[excel.xlsx]DATA'!B2 - '[excel.xlsx]DATA'!A3)", "'[excel.xlsx]DATA'!C3": "=(('[excel.xlsx]DATA'!C2 * '[excel.xlsx]DATA'!A2) + '[excel.xlsx]DATA'!D3)", "'[excel.xlsx]DATA'!D3": "=(1 + '[excel.xlsx]DATA'!D2)", "'[excel.xlsx]DATA'!B4": "=MAX('[excel.xlsx]DATA'!A3:A4, '[excel.xlsx]DATA'!B2)", "'[excel.xlsx]DATA'!C4": "=(('[excel.xlsx]DATA'!B3 ^ '[excel.xlsx]DATA'!C2) + '[excel.xlsx]DATA'!D4)", "'[excel.xlsx]DATA'!D4": "=(1 + '[excel.xlsx]DATA'!D3)" } >>> xl_json = json.dumps(xl_dict, indent=True) # To JSON. >>> xl_model = formulas.ExcelModel().from_dict(json.loads(xl_json)) # From JSON.
自定义函数
以下是如何将自定义函数添加到公式解析器的示例
>>> import formulas >>> FUNCTIONS = formulas.get_functions() >>> FUNCTIONS['MYFUNC'] = lambda x, y: 1 + y + x >>> func = formulas.Parser().ast('=MYFUNC(1, 2)')[1].compile() >>> func() 4
项目详情
下载文件
下载适合您平台的应用程序。如果您不确定选择哪一个,请了解更多关于安装包的信息。