V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
wxiao333
V2EX  ›  Python

excel 公式作为算法程序,可行吗?

  •  
  •   wxiao333 · 2022-02-16 17:34:22 +08:00 · 4623 次点击
    这是一个创建于 1012 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有这么一个需求: 把一个巨复杂的 excel 里面的公式代码化,这个 excel 有多复杂呢,大概 10 几个 sheet ,每个 sheet 里面都有大量公式计算,一共有 50 多个输入参数,50 多个输出量,中间环节变量超过 1000 个。。。

    现在要把这个 excel 代码化,工作量是蛮大的,想到一个办法:

    能不能把这个 excel 当做一个计算程序,参数丢给 execl 输入数据的相应位置,立马就能出计算结果,去相应位置获取结果即可,省去了编码。

    这个需求 python 或其他语言下 有可以实现的库吗 或者有其他更好的解决方案吗?

    28 条回复    2023-03-01 09:41:58 +08:00
    ttys001
        1
    ttys001  
       2022-02-16 17:41:16 +08:00   ❤️ 1
    你说的这些大量公式是指什么?如果是加减乘除三角函数对数和幂这类初等运算,python 搞这种不要太轻松~
    lyquan
        2
    lyquan  
       2022-02-16 17:46:38 +08:00
    R 语言处理可能会简单点,读取,计算,输出都有相应的包
    czfy
        3
    czfy  
       2022-02-16 17:49:32 +08:00
    excel 做计算,理论上应该会很慢
    ospider
        4
    ospider  
       2022-02-16 17:58:05 +08:00
    完全可以搞啊,如果你这个每分钟请求在个位数的话。估计得用一台 Windows 的机器,然后用 COM 操纵 Excel 就行了。如果要转 Python 代码的话,你可能需要把这些公式都转换成 AST ,然后再生成 Python……相当于写了一个 Excel 到 Python 的编译器
    wxiao333
        5
    wxiao333  
    OP
       2022-02-16 18:07:52 +08:00
    @ttys001 现在的痛点其实是不想写这么多业务代码,excel 相当于已经有了业务代码,就想直接用这个东西。
    wxiao333
        6
    wxiao333  
    OP
       2022-02-16 18:08:27 +08:00
    @ospider 谢谢哈,请问下 AST 全称叫什么,我研究下
    Origami404
        7
    Origami404  
       2022-02-16 18:08:29 +08:00 via Android
    我觉得要是不怕麻烦的话,可以写一个工具来总结这些单元格的依赖,比如 a3=a1+a2 之类的;然后这就是一颗表达式树,下次输入直接表达式求值就可以了。但是如果 excel 里使用了很多 excel 函数的话可能还得造很多轮子,而且一些依赖(比如 vlookup )不是那么好总结的
    wxiao333
        8
    wxiao333  
    OP
       2022-02-16 18:08:48 +08:00
    @czfy 慢点没关系,能实现功能就行,这个需求对速度要求一般
    lntouchables
        9
    lntouchables  
       2022-02-16 18:12:52 +08:00
    可以做,我们这边刚开始做对速度要求不高的时候就是起一个 windows 服务器,在上面操作 excel 算的,最后拿个结果
    gengchun
        10
    gengchun  
       2022-02-16 18:13:51 +08:00
    Python 的话,有一个叫 formulas 的包,干这个事情的。不过有些学习成本。

    https://formulas.readthedocs.io/en/stable/doc.html
    czfy
        11
    czfy  
       2022-02-16 18:16:24 +08:00
    @wxiao333 呃为什么不考虑把数据 import 到 python 做完计算再导出 excel ?
    kkocdko
        12
    kkocdko  
       2022-02-16 18:22:10 +08:00
    @wxiao333 AST 是“抽象语法树”

    低性能+高兼容性:建议还是依赖 Excel 裹一层会比较好,如 4# 所说的方案。

    中等性能+一般兼容性:openpyxl ,相当于一个特殊的 Excel 实现,不支持某些犄角旮旯的公式。
    ttys001
        13
    ttys001  
       2022-02-16 18:54:24 +08:00
    @wxiao333
    你的意思是现在这个 excel 已经弄好了这一堆乱七八糟的计算公式了,有没有什么包能够把 excel 表导入进 python 后自动生成这些计算公式的 py 代码?
    听上去是个不错的需求🤔
    wxiao333
        15
    wxiao333  
    OP
       2022-02-16 19:06:25 +08:00
    @czfy 计算过程太复杂,上千个步骤和中间变量,不想去写这些业务代码,而且还要先花时间去理解这个流程,理解错了的话还容易出 bug 。
    secondwtq
        16
    secondwtq  
       2022-02-16 19:24:42 +08:00
    理论上当然可行,但是你在什么场景下用呢,比如你要放 Linux 服务器上跑那可能有些库就没法用
    Jooooooooo
        17
    Jooooooooo  
       2022-02-16 19:28:22 +08:00
    肯定是可以的, 因为 excel 图灵完备.
    kilasuelika
        18
    kilasuelika  
       2022-02-16 20:28:06 +08:00
    @wxiao333 没必要搞 AST 那些,这个是计算机科学领域比较专业的东西。

    你的需求实现是很简单的,首先用 python 操作 excel 文件(比如 openpyxl )在指定位置写入数据。然后在 python 中调用函数用 excel 打开这个文件( win32com.client ),excel 会自动进行计算,再保存这个文件。接着再打开这个文件读取指定位置的数据就可以了。
    kilasuelika
        19
    kilasuelika  
       2022-02-16 21:00:35 +08:00
    @wxiao333 给你一段测试代码:

    # 处理路径
    from pathlib import Path

    # 创建一个带公式 Excel
    from openpyxl import Workbook

    wb = Workbook()
    excel_file = 'original_book.xlsx'
    calculate_excel_file="cal_book.xlsx"

    ws = wb.create_sheet(title="NewSheet")
    ws['A1']=5
    ws['A2']=7
    ws['A3']="=A1+A2" #创建一个公式

    wb.save(excel_file)

    #调用 win32com 进行计算
    import win32com.client as win

    excel=win.Dispatch('Excel.Application')
    excel.DisplayAlerts = False
    target_wb=excel.Workbooks.Open(str(Path(excel_file).absolute())) #注意要完整路径
    target_wb.SaveAs(Filename=str(Path(calculate_excel_file).absolute()))
    target_wb.Close()


    # 打开计算过的文件
    from openpyxl import load_workbook
    wb = load_workbook(filename = calculate_excel_file, data_only=True) #要加 data_only ,要不然输出的还是公式。
    sheet = wb['NewSheet']
    print(sheet['A3'].value) #输出 12
    a132811
        20
    a132811  
       2022-02-16 21:26:46 +08:00
    可以,你要先熟悉一下关于 excel 的 sdk (主要是 openpyxl ),就是 @kilasuelika 给的例子那样

    另外我写过一个 excel 解析、保存工具: https://github.com/ahuigo/xlparser 或许对你有帮助
    akira
        21
    akira  
       2022-02-16 23:12:52 +08:00
    vba ,c#,delphi 做这个事情都很容易。但是稳定性才是最大的问题
    wxiao333
        22
    wxiao333  
    OP
       2022-02-17 08:51:41 +08:00
    @kilasuelika 非常感谢,我仔细研究下
    wxiao333
        23
    wxiao333  
    OP
       2022-02-17 08:52:01 +08:00
    @a132811 谢谢,我研究下您的工具
    mindset
        24
    mindset  
       2022-02-17 09:17:39 +08:00
    我做过这方面的工作。
    1 ,首先,我用 java 语言写了程序把 excel 文件转成 xml 文件,便于读取。
    2 ,我写过一个 c 语言的,另一个是 Swift 语言的库,用于把 xml/excel 里的公式进行解析和运算。
    3 ,多个 sheet 可以一起运算,从左到右从上到下运算,把结果写回 sheet 中。运算效率还不错。
    4 ,我的这个项目已经实际应用于某保险公司的 app 中。
    如果你需要,我可以写一个任意语言的 excel sheet 运算引擎。其实都是类似。
    shinession
        25
    shinession  
       2022-02-17 09:29:02 +08:00 via Android
    xlwings ?直接调用 excel 计算,不用写多少代码
    churchill
        26
    churchill  
       2022-02-17 11:03:00 +08:00
    为啥要强调 python
    干这事 c#写一个 vsto add-in 开一个 web-service 比用 python 香吧
    wxiao333
        27
    wxiao333  
    OP
       2022-02-19 21:30:38 +08:00
    更新一个后续吧,目前选择用 xlwings 这个包实现了功能,这个包有一点好处是他本身是基于 win32com 的,所以等于是在后台把这个 excel 文件给打开了,然后直接操作,实时写入数据,读取结果,非常方便。缺点是速度比较慢,特别是初次打开需要 2,3 秒的时间,相当于打开一个 excel 文件的时间。另一个缺点是需要 win 服务器和安装 excel ,不过我装了 office2007 就可以正常运行。另一个缺点是多线程方面的,这个有很多处理方式,大家可以自己搜索一下。
    dragonszy
        28
    dragonszy  
       2023-03-01 09:41:58 +08:00
    也有类似的大表格计算需求,能达到 Excel 或者 WPS 原始计算速度的不多。开源的库基本加载不了大量嵌套计算的表格。测试下来 WebWPS ,OnlyOffice 和 SpreadJS 可以计算。Python 库 PyCel ,Go 的 Excelize 均无法完成计算。xlwings 是一个解决方案,但是得 windows 服务器。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4578 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 37ms · UTC 01:10 · PVG 09:10 · LAX 17:10 · JFK 20:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.