Python Excel 配置编辑器

配置工作经常需要同时打开几张 Excel:找字段、对照含义、检查数值,再确认有没有改错列。我希望把这些重复操作收进一个可视化页面,让表格继续承担数据存储,让工具承担输入提示和校验。

这篇先把最小流程做完整:上传一张约定格式的配置表,修改三个字段,下载一份新文件。完整源码、示例表和测试都附在文中;目录扫描、多语言生成、增删行和打包 EXE 仍属于后续设计。

先解决一个具体问题

例如,一个模块需要配置最大玩家数、掉落概率和欢迎语。在 Excel 里,它们都可以放进“值”这一列,但三者的规则不同:玩家数必须是整数,概率只能在 0 到 1 之间,欢迎语应该是文字。

如果只把单元格搬到网页,再允许随意写回,错误仍然会发生。这个工具首先要表达字段含义和约束,再处理读写。

我选择 Python,是因为读写表格、组织业务规则和测试比较方便;Flask 提供本地页面与接口,openpyxl 处理 .xlsx。HTML 表单可以按字段类型提供输入框,后续也容易增加模块。这里并不意味着 VBA 不适合 Excel 自动化,只是这条路线更符合把配置规则拆成独立模块的目标。

下载并运行最小示例

下载完整示例 ZIP · 只下载示例工作簿

解压后,在 excel-config-demo 目录中操作。需要 Python 3.10 或更新版本;本文实际验证环境为 Python 3.12.14、Flask 3.1.2、openpyxl 3.1.5。依赖版本是本示例的验证基线,不代表最新版本。首次安装依赖需要联网,启动后没有 CDN 或远程接口。

Windows PowerShell:

1
2
3
py -3 -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
.\.venv\Scripts\python.exe app.py

macOS / Linux:

1
2
3
python3 -m venv .venv
.venv/bin/python -m pip install -r requirements.txt
.venv/bin/python app.py

使用虚拟环境可以把示例依赖和其他 Python 项目分开;以上直接调用环境内的 Python,不需要激活脚本。Flask 安装说明

启动示例后,打开本机编辑页面,按页面完成四步:

  1. 点击“先下载示例工作簿”,或使用 ZIP 中的 config-sample.xlsx。
  2. 选择文件,点击“读取并校验”。
  3. 修改三个字段,比如把最大玩家数从 100 改为 321。
  4. 点击“校验并下载副本”,得到 config-edited.xlsx,再用 Excel 检查。

选择新文件后,旧编辑表单会清空,必须重新读取。输入 0 个玩家或 1.2 的概率会被拒绝。服务不会改写原文件;如果浏览器询问保存位置,请为副本选择新文件名。停止示例用终端的 Ctrl+C。端口占用时,先关闭占用程序,或调整 app.py 最后一行的端口。

这是本机开发示例,监听地址限定为 127.0.0.1,关闭调试器和自动重载。Flask 官方不建议把内置开发服务器用于正式部署,即使只有本机单用户也要区分开发演示与生产使用。Flask 部署说明

先约定表格,再写接口

工作簿必须有一张名为“配置”的工作表,A1:C1 依次为“键”“值”“说明”。三个键各出现一次,顺序可以调整;工具按键寻找对应 B 列单元格。

键 示例值 服务端规则
max_players 100 1–10000 的整数,不把文字或布尔值当数字
drop_rate 0.25 0–1 的有限数字,0.25 表示 25%
welcome_text 欢迎进入游戏 1–80 字非空文字,不接受控制字符或以等号开头的公式

接口只接收上传文件和这三个键的新值,不能传服务器路径、工作表名或任意单元格地址。文件名只用于判断 .xlsx 后缀,不用于拼接磁盘路径。读取文件后,服务端检查表头、重复键、字段类型和取值范围;导出时还会重新检查一次,不能只依赖网页的输入控件。

为控制这个示例的处理范围,上传文件限制为 2 MiB,ZIP 解压总量最多 10 MiB、128 个部件;工作簿最多 4 张表,每张表的使用范围最多 1000 行、20 列。代码不把上传文件永久保存到目录,但 Flask 在处理较大上传时可能使用系统临时文件,因此不应把它描述为“全程只在内存”。Flask 文件上传说明

模块之间如何分工

1
2
3
4
5
6
7
8
9
10
excel-config-demo/
├─ app.py # Flask 路由、上传与下载
├─ workbook_io.py # 表结构、字段校验、读写
├─ templates/index.html # 上传和编辑表单
├─ static/app.js # 预览、错误提示、下载
├─ static/style.css
├─ config-sample.xlsx
├─ requirements.txt
├─ test_app.py
└─ README.md

workbook_io.py 不认识 HTTP,也不接收磁盘路径,公开三个主要函数:

函数 输入 输出
inspect_workbook(data) 上传文件的字节 字段名、类型、原值和说明
edit_workbook(data, changes) 原文件字节与三个新值 新工作簿字节
make_sample() 无 示例工作簿字节

前端保留用户选择的 File。预览时上传一次;导出时把同一份原文件和新值一起提交。服务不缓存全局工作簿,两个浏览器页面不会共用一个正在编辑的 Python 对象。未下载的表单修改只存在于当前页面,刷新会丢失。

下面是下载包里的关键片段,用于解释流程;完整运行仍需包内的校验函数、前端和其余路由。

1
2
3
4
5
6
7
8
9
10
11
# workbook_io.py:校验成功后,在载入的原单元格上改值
values = {key: validate_value(key, changes[key]) for key in FIELDS}
workbook, positions = open_config(data)
try:
for key, value in values.items():
workbook["配置"].cell(positions[key], 2).value = value
result = BytesIO()
workbook.save(result)
return result.getvalue()
finally:
workbook.close()

这里没有从 JSON 重建整张表。只修改原单元格的 value,更容易保留其已有样式;保存目标也是新的字节流,而不是原文件路径。

1
2
3
4
5
6
7
8
# app.py:固定副本名,不使用上传者给出的文件路径
result = edit_workbook(original, changes)
return send_file(
BytesIO(result),
mimetype="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
as_attachment=True,
download_name="config-edited.xlsx",
)

send_file 可以发送二进制文件对象,as_attachment 和 download_name 指定下载行为与文件名。这里采用当前参数名,没有沿用旧版的 attachment_filename。Flask API

格式保留的边界

样例验证了填色、字体、百分比格式、列宽和冻结窗格的往返保留,备注表中的公式也保留为公式。这只是这个工作簿与这些属性的验证结果,不能推出任意 Excel 文件都无损。

读入时使用 data_only=False 保留公式表达式,rich_text=True 请求保留已有富文本。openpyxl 官方说明它不能读取 Excel 的全部对象,部分形状可能在重新保存时丢失。因此,示例拒绝已识别的图形、图表、外部工作簿链接、嵌入对象及宏,也不接受配置区的合并或保护单元格;遇到其他高级特性仍需独立检查。openpyxl 读入选项与限制

另外要分开两件事:

  • 保存公式不等于计算公式。 openpyxl 不执行公式。本例的备注公式 =配置!B2*2 会保留,但下载后的缓存计算结果可能为空;需要由 Excel 等计算程序重新计算,网页不会把 642 当作已经算出的结果。openpyxl 公式说明
  • 修改值不等于正确增删行。 openpyxl 插入或删除行列时,不会自动维护所有公式、表格或图表依赖。本文暂不开放增删行,后续需要为具体模块定义引用更新规则并测试。openpyxl 行列操作说明

宏工作簿也有独立契约:keep_vba=True 只涉及保留 VBA 内容,并不意味着可以编辑或执行 VBA。本例明确只收 .xlsx,没有实现 .xlsm 支持。openpyxl 工作簿选项

如何验证它确实能跑

下载包带有 12 个 unittest 测试。在同一目录运行:

1
.\.venv\Scripts\python.exe -m unittest -v

macOS / Linux 将 Python 路径换成 .venv/bin/python。

测试覆盖上传预览、修改后重读、样式和公式保留、原字节不变、错误类型、越界值、重复或缺失键、路径输入、错误格式、宏与复杂部件拒绝、两种大小限制。另有一个测试启动随机空闲端口的本地 WSGI 服务,通过真实 HTTP 下载修改后的 Excel,结束后自动关闭。

2026-09-08 在上述版本环境中,这 12 项测试通过;真实 HTTP 导出也完成。Flask 测试客户端用于大部分接口检查,与真实服务器检查互补。Flask 测试说明

这些结果证明了本文的服务流程和样例文件往返,没有替代桌面 Excel 的显示检查或公式计算。把副本用于实际配置前,仍应打开核对字段、格式和结果。

后续扩展

原先希望做的多表联动、时装属性展开、多语言生成和可配置错误提示,都可以从字段契约继续扩展:先写纯 Python 的规则和测试,再把预览结果放到页面中确认,最后才写回副本。

目录扫描、全文搜索、增删行、撤销历史和打包单文件 EXE,本示例没有实现。下一步应选择一个实际模块补齐规则,而不是先堆叠一组尚无后端实现的接口。最小版本先确保读得明白、改得有约束、输出可核对。