查看: 99|回复: 3

Python xlwings 批量统一多个 Excel 工作簿的日期、金额与百分比显示格式

[复制链接]
发表于 1 小时前 | 显示全部楼层 |阅读模式
在办公自动化中,经常遇到多个部门提交的 Excel 报表格式不统一的问题,比如日期有的显示为 2026/1/1,有的显示为 2026-01-01;金额有的没有千分位,有的保留不同小数位;百分比有的显示为 0.1234,有的显示为 12.34%。如果人工逐个修改几十个工作簿,效率低且容易出错。本文介绍如何使用 Python 的 xlwings 库,批量扫描文件夹中的所有 Excel 文件,动态识别数据区域末端行号,然后对指定列设置 number_format 来统一显示格式,并附带验证脚本确保改版生效。
  1. import os
  2. import xlwings as xw
  3. # ====== 可修改参数 ======
  4. folder_path = r"e:\file\target"  # 存放所有 Excel 文件的文件夹
  5. sheet_name = "Sheet1"          # 要处理的工作表名称
  6. # ==========================
  7. app = xw.App(visible=False, add_book=False)
  8. try:
  9.     for file in os.listdir(folder_path):
  10.         # 跳过 Excel 临时文件
  11.         if file.startswith("~$"):
  12.             continue
  13.         # 只处理 .xlsx, .xls, .xlsm 文件
  14.         if not file.lower().endswith((".xlsx", ".xls", ".xlsm")):
  15.             continue
  16.         full_path = os.path.join(folder_path, file)
  17.         wb = None
  18.         try:
  19.             wb = app.books.open(full_path)
  20.             # 检查目标工作表是否存在
  21.             sheet_names = [s.name for s in wb.sheets]
  22.             if sheet_name not in sheet_names:
  23.                 print(f"跳过:{file},不存在工作表:{sheet_name}")
  24.                 continue
  25.             sht = wb.sheets[sheet_name]
  26.             # 动态获取连续数据区域的末行(以 A1 单元格为基准)
  27.             last_row = sht.range("A1").current_region.last_cell.row
  28.             if last_row < 2:
  29.                 print(f"跳过:{file},没有有效数据")
  30.                 continue
  31.             # 定义各列区域(假定:A列日期,B列金额,C列百分比)
  32.             rng_date = sht.range(f"A2:A{last_row}")
  33.             rng_amount = sht.range(f"B2:B{last_row}")
  34.             rng_rate = sht.range(f"C2:C{last_row}")
  35.             # 设置显示格式
  36.             rng_date.number_format = "yyyy-mm-dd"
  37.             rng_amount.number_format = "#,##0.00"
  38.             rng_rate.number_format = "0.00%"
  39.             wb.save()
  40.             print(f"已更改数据格式:{file},末行:{last_row}")
  41.         finally:
  42.             if wb is not None:
  43.                 wb.close()
  44. finally:
  45.     app.quit()
复制代码

关键逻辑解析
- current_region.last_cell.row:从 A1 出发,找到当前连续单元格区域的最后一个单元格的行号,从而实现动态适应不同工作簿的数据行数。如果数据区域中间有整行空行,该区域可能提前结束,所以应确保待处理表格中无空白行隔断数据。
- number_format:只改变 Excel 的显示规则,不修改底层数值。如果单元格内容本质上是文本(如“2026/1/1”是字符串而非日期),单纯设置 number_format 可能不会立即生效,需要配合数据类型转换。
- 异常防护:跳过 ~$ 开头的临时文件;检查工作表是否存在;如果只有表头没有数据(last_row < 2)则跳过;使用 try/finally 确保每个工作簿正确关闭,避免进程残留。

操作建议
1. 正式执行前,先复制一份测试目录,放入 2~3 个样例文件验证效果。
2. 确认工作表名称和列顺序与脚本一致。如果表头不在第 1 行,或需要按表头文字动态定位,可结合 xlwings 的 .expand() 或 .api 属性增强。
3. 批量处理时,建议先在脚本内打印文件名和识别的末行:
  1. print(f"当前文件:{file}")
  2. print(f"识别到的数据末行:{last_row}")
复制代码
这样便于快速定位结构异常的文件。

验证脚本
处理完成后,建议用只读脚本抽查格式:
  1. import os
  2. import xlwings as xw
  3. folder_path = r"e:\file\target"
  4. sheet_name = "Sheet1"
  5. app = xw.App(visible=False, add_book=False)
  6. try:
  7.     for file in os.listdir(folder_path):
  8.         if file.startswith("~$") or not file.lower().endswith((".xlsx", ".xls", ".xlsm")):
  9.             continue
  10.         full_path = os.path.join(folder_path, file)
  11.         wb = None
  12.         try:
  13.             wb = app.books.open(full_path)
  14.             if sheet_name not in [s.name for s in wb.sheets]:
  15.                 print(f"跳过:{file}")
  16.                 continue
  17.             sht = wb.sheets[sheet_name]
  18.             print(f"文件:{file}")
  19.             print("A2 日期格式:", sht.range("A2").number_format)
  20.             print("B2 金额格式:", sht.range("B2").number_format)
  21.             print("C2 百分比格式:", sht.range("C2").number_format)
  22.             print("-" * 40)
  23.         finally:
  24.             if wb is not None:
  25.                 wb.close()
  26. finally:
  27.     app.quit()
复制代码
该脚本不修改文件,只读取 number_format 属性,可以快速确认格式是否已写入。

常见陷阱与延伸
- 文本型数据:如果单元格左上角有绿色三角(Excel 的智能标记),说明该单元格以文本形式存储数字/日期。仅靠 number_format 无法将其转换为真实数值或日期,需要先用 xlwings 的 .value 覆盖或使用 Excel 的“分列”功能。
- 外观格式扩展:除了 number_format,还可以用 .api 设置字体、边框、对齐、底色等,例如:
  1. header_rng = sht.range("A1:C1")
  2. header_rng.api.Font.Bold = True
  3. header_rng.api.HorizontalAlignment = -4108  # 居中
  4. header_rng.color = (217, 217, 217)        # 浅灰色底色
复制代码
不过外观格式依赖本地 Excel 环境,批量处理前需在典型机器上测试。

总结
批量统一多个工作簿的显示格式,是用 Python 做 Excel 自动化的典型实践。核心在于动态获取数据范围(current_region.last_cell.row)并精准设置 number_format。本文提供的代码已包含临时文件跳过、工作表检查、末行验证、格式写入和结果验证,可直接用于实际场景。记住:格式规范是数据质量的一部分,将规则固化为脚本,才能实现真正可复用的报表标准化工具。
回复

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: Python xlwings 批量统一多个 Excel 工作簿的日期、金额与百分比显示格式

感谢分享这么实用的批量格式统一方案!用 `current_region` 动态定位末行确实很巧妙,避免了死板指定行数带来的适配问题。而且你特别提到了 `number_format` 只改显示不改底层数值,以及文本型日期可能失效的坑,这对实际落地很有参考价值。如果表格中有合并单元格或间断空行,可以再加一层 `used_range` 或其他容错判断,但对大多数连续报表来说已经足够。另外验证脚本的思路也很值得学习——改完后抽查一下,心里踏实多了。收藏了,回头遇到乱格式报表时就拿这个模板来改!
回复 支持 反对

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: Python xlwings 批量统一多个 Excel 工作簿的日期、金额与百分比显示格式

这个脚本很实用,正好解决了多部门报表格式不统一的痛点。用了 `current_region.last_cell.row` 动态获取末行,比硬编码行号灵活多了。提个小的补充:如果数据区域中间有空白列或表格不连续,`current_region` 可能只取到空白前的区域,建议先确认表格结构是否紧凑。另外,日期文本格式的问题我也遇到过,可以在设置 `number_format` 之前先用 `sht.range(...).value = sht.range(...).value` 触发一次数值转换,或者配合 `xlwings` 的 `api` 强制将文本转成日期数字。整体思路清晰,验证脚本的加入也很贴心,收藏了!
回复 支持 反对

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: Python xlwings 批量统一多个 Excel 工作簿的日期、金额与百分比显示格式

这个脚本非常实用,尤其对经常处理报表格式的办公场景来说,能省下大量重复劳动。动态获取末行和跳过临时文件的设计很贴心,避免了不少坑。不过有个小建议:脚本里固定了 A 列日期、B 列金额、C 列百分比,如果实际表格的列顺序不一致,或者表头行数不固定,可能需要额外处理。比如可以先用 `.expand()` 定位表头行,再根据表头文字动态匹配列号,这样通用性会更强。感谢分享,收藏了!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-7-1 11:25 , Processed in 0.036232 second(s), 18 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部