Excel Python:飞速搞定数据分析与处理

第四部分 使用 xlwings 对 Excel 应用程序进行编程
第十章 Python 驱动的 Excel 工具
第 9 章介绍了如何编写脚本来自动化 Microsoft Excel。虽然这些脚本很强大,但它们需要用户能够熟练使用 Anaconda Prompt 或者像 VS Code 这样的编辑器来运行脚本。如果你的工具是给商业用户使用的,那么这样的要求可能就不太现实。对于这样的用户,你会想要将 Python 隐藏起来,从而让这些 Excel 工具感觉像是普通的带有宏的工作簿那样,而如何使用 xlwings 达到这样的效果便是本章的主题。本章首先会向你展示如何用最简单的方法 在 Excel 中执行 Python 代码。然后会挑战一下部署 xlwings 工具,在这个过程中我们会对 xlwings 提供的各种选项有一个更细致的了解。和第 9 章一样,本章也需要你在 Windows 或者 macOS 中安装好 Microsoft Excel。
10.2 部署
在软件开发领域,部署 (deployment)这一术语指的是分发并安装 软件,从而让终端用户能够使用该软件。对于 xlwings 工具来说,这个过程可以帮助我们了解到存在哪些依赖项, 哪些设置可以让部署过程更方便。本节会从最重要的依赖项(也就是 Python)讲起。随后会研究处于独立模式下的工作簿,在独立模式下这些工作簿不再需要 xlwings 的 Excel 插件。本节在最后会详细研究如何配置 xlwings。
10.2.1 Python 依赖
为了能够运行 xlwings 工具,你的终端用户(即他人)必须安装 Python。但未安装 Python 并不意味着没有可以简化安装过程的方法。下面有一些方法可供选择。
Anaconda 或 WinPython
指导你的用户下载并安装 Anaconda 发行版。为安全起见,你需要指定特定版本的 Anaconda 以确保你的用户所使用的包的版本和你一样。如果你使用的都是包含在 Anaconda 中的包,那么这是一种好办法。WinPython 基于 MIT 开源许可分发,并且也预装了 xlwings,用它来代替 Anaconda 也不错。正如其名字所示,WinPython 只能在 Windows 中使用。
共享驱动器
如果可以访问一个相对较快的共享驱动器,那么你可以直接在上面安装 Python,这样每个人都可以使用这些工具而无须在本地安装 Python。
冻结可执行文件
在 Windows 中,xlwings 可以让你创建冻结可执行文件(frozen executable)。冻结可执行文件以 .exe 为扩展名,其中包含了 Python 以及所有依赖项。PyInstaller 是一个可以生成冻结可执行文件的流行包。冻结可执行文件的优势在于它们可以将程序所需要的所有东西打包成单个文件,这样分发起来就更方便了。有关如何使用冻结可执行文件的更多细节,可以参看 xlwings 的文档。注意,如果你把 xlwings 用到了用户定义函数(第 12 章会介绍)上,那么冻结可执行文件就无法工作了。
10.2.2 独立工作簿:脱离 xlwings 插件
在本章中,无论是点击 Run main 按钮还是使用 RunPython 函数,我们总是依赖于 xlwings 插件来调用 Python 代码。即使利用 xlwings CLI 安装插件很简单,但是对于对技术不那么了解的用户来说,Anaconda Prompt 用起来也不是很简单。另外,由于 xlwings 插件和 xlwings 的 Python 包的版本需要保持一致,因此如果你的用户已经安装了 xlwings,但是版本和你的工具所需的版本不一致,这就可能会造成冲突。不过也有一种简单的解决方案: xlwings 并不一定要安装 Excel 插件,它可以被设置为独立工作簿(standalone workbook)。 在这种情况下,插件的 VBA 代码会被直接保存在工作簿中。和往常一样,进行这一系列配置的最简单的方法就是使用 quickstart 命令,这次要用到 --standalone 标志:
(base)> xlwings quickstart second_project --standalone
当你在 Excel 中打开命令生成的 second_project.xlsm 工作簿并按下快捷键 Alt+F11(Windows 系统)或 Option-F11(macOS 系统)时,可以看到 xlwings 模块和 Dictionary 类模块取代了插件。最重要的一点是,独立项目不能再引用 xlwings。虽然这些都可以通过 --standalone 标志自动配置,但是值得注意的是,如果你想将一个现有的工作簿转换为独立工作簿,就需要在引用中移除 xlwings:进入 VBA 编辑器的 "工具>引用" 菜单中,取消勾选 xlwings 的复选框。

构建自定义插件 :虽然本节展示的是如何脱离对 xlwings 插件的依赖,但是有时候你可能想要在部署过程中构建自己的插件。如果你想在大量不同的工作簿中使用同样的宏,那么这样做是理所当然的。你可以在 xlwings 的文档中找到关于构建自定义插件的说明。
介绍完 Python 和插件之后,现在来深入了解一下 xlwings 的配置是如何工作的。
10.2.3 配置的层次关系
正如本章开头提到的那样,功能区将配置保存在用户的 home 目录的 .xlwings\xlwings.conf 中。配置包含了独立的设置,就像我们在本章开头看到过的 PYTHONPATH 那样。插件的设置可以在目录级别和工作簿级别上进行覆盖。xlwings 按照如下位置和顺序查找设置。
- 工作簿配置 首先,xlwings 会查找一张叫作 xlwings.conf 的工作表。这是在部署时配置工作簿的推荐方法,不需要处理额外的配置文件。当你执行 quickstart 命令时,它会在一张叫作 "_xlwings.conf " 的工作表上创建示例配置:删除开头的下划线就可以启用配置。如果不想使用这个配置,则可以随意删除这张工作表。
- 目录配置 接下来,xlwings 会在你的 Excel 工作簿所在目录查找一个叫作 xlwings.conf 的文件。
- 用户配置 最后,xlwings 会在用户的 home 目录的 .xlwings 文件夹中查找一个叫作 xlwings.conf 的文件。通常,你不会直接编辑这个文件,也就是说,每当你修改设置时这个文件都会被插件创建和编辑。
如果 xlwings 在这 3 个位置中都找不到 任何设置,则它会后退使用默认值。
当你通过 Excel 插件编辑设置时,插件会自动编辑 xlwings.conf 文件。如果你想直接编辑这个文件,那么可以在 xlwings 文档中查询具体的格式和可用的设置。不过后面在讲解部署时会指出最有用的设置。
10.2.4 设置
最关键 的设置自然是 Python 解释器的设置,也就是说,如果你的 Excel 工具找不到正确的 Python 解释器,那么它便无法发挥任何作用。PYTHONPATH 设置使你能够控制放置 Python 源文件的位置。在 Windows 中启用 "Use UDF Server"(使用 UDF 服务器)设置可以在每次调用过程中保持 Python 解释器一直运行,这样可以极大地提升性能。
Python 解释器
xlwings 依赖于本地安装的 Python。然而这并不一定就意味着你的 xlwings 用户在能够使用工具之前必须进行一番设置。正如前面提到的那样,你可以告诉他们使用默认设置安装 Anaconda 发行版,该发行版会被安装在用户的 home 目录中。如果你在配置中使用了环境变量,那么 xlwings 将找到 Python 解释器的正确路径。环境变量是在用户计算机上设置的一种变量,它们可以让程序查询该环境中的各种信息,比如当前用户 home 文件夹的名称。举例来说,在 Windows 中,将 Conda Path 设置为 %USERPROFILE%\ anaconda3,在 macOS 中,将 Interpreter_Mac 设置为 $HOME/opt/anaconda3/bin/python。 这些路径会被动态地解析为 Anaconda 的默认安装路径。
PYTHONPATH
在默认情况下,xlwings 会在 Excel 文件所在目录中查找 Python 源文件。如果你的用户并不熟悉 Python,那么当他们在移动 Excel 文件时可能会忘记一并移动 Python 源文件,这个时候利用 xlwings 的默认设置就不太好了。此时你可以将 Python 源文件放到一个专门的文件夹 中(可能是一个共享驱动器上的位置),然后将这个文件夹添加 到 PYTHONPATH 设置中。另外,你也可以将源文件放到一个已经是 Python 模块搜索路径的一部分的文件夹中。实现这一行为的方法之一是以 Python 包的形式分发你的源代码, 也就是说,Python 包在安装时会被放到 Python 的 site-packages 目录中,Python 会在这里找到你的代码。有关构建 Python 包的更多信息,参见 Python Packaging User Guide。
RunPython:Use UDF Sever(仅限 Windows 系统)
你可能注意到了,RunPython 调用会相当慢。这是因为 xlwings 会启动一个 Python 解释器,然后运行 Python 代码,最后再关闭解释器。在开发过程中这个问题可能没那么严重,因为这个过程可以保证每次调用 RunPython 时都能够重新加载所有模块。不 过,一旦代码稳定下来了,你可能就想勾选 "RunPython: Use UDF Server" 选项(仅限 Windows 系统)。该选项会使用与用户定义函数相同的 Python 服务器(这是第 12 章的主题),并且在每次调用之间保持 Python 会话持续运行 ,这会让调用过程变快不少。不过要注意的是,你需要在修改代码后 点击功能区的 "Restart UDF Server"(重启 UDF 服务器)按钮。
10.3 小结
本章首先展示了从 Excel 中调用 Python 代码有多简单:安装好 Anaconda 之后,只需执行 xlwing addin install 命令,然后再执行 xlwings quickstart myproject,接下来就可以点击 xlwings 插件中的 Run main 按钮或者使用 VBA 中的 RunPython 函数了。然后本章介绍了一些可以简化 xlwings 工具部署过程的设置。事实上,由于 Anaconda 预装了 xlwings, 因此新用户面临的门槛也就大大降低了。
l 中调用 Python 代码有多简单:安装好 Anaconda 之后,只需执行 xlwing addin install 命令,然后再执行 xlwings quickstart myproject,接下来就可以点击 xlwings 插件中的 Run main 按钮或者使用 VBA 中的 RunPython 函数了。然后本章介绍了一些可以简化 xlwings 工具部署过程的设置。事实上,由于 Anaconda 预装了 xlwings, 因此新用户面临的门槛也就大大降低了。
在本章中,我们仅通过 Hello World 这个例子就学习了各种工具的工作原理。第 11 章会利用这些基础知识来构建一个像模像样的商业应用,即 Python 包跟踪器。