夜雨聆风学习资料网

ARTICLE · 1050686

Python办公:Word 文档批量查找替换

Python办公:Word 文档批量查找替换

🔁 word_replace · Word 文档批量查找替换

一篇 Word 里多处出现同一个旧词(公司名、年份、产品名……),想一键全部替换成新词。正文段落和表格里的词都不会漏。

适用人群

  • • 行政 / 文秘:合同模板里公司名变更、年度更迭,批量替换全篇。
  • • 老师:试卷 / 课件里统一改术语、改年份。
  • • 运营 / 编辑:稿子里品牌词、活动名统一更新。
  • • 任何人:手里有一堆 .docx,要做全文级的「查找-替换」。

功能简介

  • • 读取一篇 Word(testdata/doc.docx)和一份替换规则 JSON({"旧词":"新词"})。
  • • 遍历所有段落所有表格单元格执行替换,不留死角。
  • • 兼容「词被拆到多个 run(格式片段)」的情况,替换不漏、格式尽量保留。
  • • 输出 output/doc_replaced.docx,并回显是否还有残留旧词。
  • • 文件 / 规则缺失时给出友好提示,JSON 格式错误也会被捕获。

环境准备

pip install python-docx

本项目用 python-docx 1.2.0 验证。替换规则是纯 JSON,无需额外依赖。

使用方法

# 1) 生成测试素材python make_testdata.py# 2) 默认运行python word_replace.py# 3) 自定义python word_replace.py --doc testdata/doc.docx --rules testdata/replace.json --out output/doc_replaced.docx

输出示例:

替换规则共 6 条,已写入:.../output/doc_replaced.docx全部旧词已替换完成,无残留。

核心代码讲解

1. 替换规则(JSON)

{"旧产品":"新产品","旧部门":"新部门","旧制度":"新制度"}

键是要被替换的旧词,值是新词;中英文皆可,也支持把长句替换成另一段文字。

2. 段落内替换思路和批量生成一致:先逐 run 替换保格式,若词被拆到多个 run 则整段拼接后替换。

defreplace_in_paragraph(paragraph, mapping):    runs = paragraph.runsifnot runs:returnfor run in runs:for old, new in mapping.items():if old in run.text:                run.text = run.text.replace(old, new)    full = "".join(r.text for r in runs)ifany(old in full for old in mapping):        new_full = fullfor old, new in mapping.items():            new_full = new_full.replace(old, new)        runs[0].text = new_fullfor r in runs[1:]:            r.text = ""

3. 表格也别漏

defreplace_in_table(table, mapping):for row in table.rows:for cell in row.cells:for para in cell.paragraphs:                replace_in_paragraph(para, mapping)

4. 残留检查替换后把正文 + 表格拼成一段文本,统计还有没有旧词——贴在新词里的旧词、页眉页脚、图片中的文字不在 python-docx 文本模型内,会在此提示,方便你人工复核。

测试素材说明

运行 make_testdata.py 后,testdata/ 下生成:

  • • doc.docx:含 2 段正文 + 1 个 4 行 2 列表格(表内也放了旧词,用来验证「表格替换」)。
  • • replace.json:6 条旧→新规则。

运行后 output/doc_replaced.docx 中:正文与表格里的「旧产品 / 旧部门 / 旧制度 / 旧问题 / 旧流程 / 旧合同」全部变为对应新词,脚本回显「无残留」。

常见问题

  • • Q:页眉 / 页脚 / 文本框里的词没被替换?A:python-docx 的 paragraphs/tables 不包含页眉页脚与文本框。如需覆盖,可额外遍历 doc.sections 的页眉页脚,或用 docx2pdf 走 Word 自身替换。本脚本会在回显中提示残留,便于你定位。
  • • Q:旧词本身也是新词的一部分,会死循环吗?A:不会。脚本一次扫描、一次性替换,不存在「替换结果再次被替换」。
  • • Q:想把旧词保留大小写形态?A:本脚本为精确匹配(区分大小写)。若需忽略大小写,可在 replace_in_paragraph 里改用不区分大小写的替换逻辑(注意新词大小写需自行指定)。
  • • Q:批量替换很多个 docx?A:当前脚本处理单个文件;把 Document() 放进遍历 testdata/*.docx 的循环即可,思路与本系列 word_extract_tables 类似。

打包成 exe

pip install pyinstaller# 单文件、无控制台pyinstaller -F -w word_replace.py
  • • -F 单文件;-w 去掉黑色控制台(想看进度就去掉 -w)。

资源路径坑本脚本用 base_dir() 取脚本所在目录作为相对路径基准,打包后不怕「当前目录」变化。但 testdata/ 不会被自动打进 exe:

  • • 方式 A(推荐):把 word_replace.exe 和 testdata/ 放一起发布。
  • • 方式 B(内置素材):
    pyinstaller -F -w --add-data "testdata;testdata" word_replace.py
    并在 base_dir() 兼容 sys._MEIPASS
    defbase_dir():ifgetattr(sys, "frozen"False):return sys._MEIPASSreturn os.path.dirname(os.path.abspath(__file__))

加图标

pyinstaller -F -w --icon=app.ico word_replace.py

瘦身

pyinstaller -F -w --upx-dir=upx word_replace.py

依赖很少(仅 docx),体积主要来自 python-docx 及其依赖,UPX 可再压一截。

常见坑

  • • 双击 exe 提示找不到 testdata/:按上面方式 A/B 处理资源。
  • • JSON 含中文却报错:确保 replace.json 是 UTF-8 编码(Windows 记事本默认存成 UTF-8 即可)。
  • • 杀软误报:单文件 exe 偶有,加白名单或目录式发布。

小结

word_replace 把「全篇查找替换」自动化,关键是同时遍历段落和表格,并兼容词被拆成多 run 的坑。理解了替换逻辑,你可以把它改成「批量处理一整个文件夹」的进阶版。

相关学习资料