Python通过win32com库操作Word教程

简介: 该教程介绍了Python中pywin32(调用win32com)库操作Word文档的方法,包含新建、写入、设置格式、插入表格、图片、查找替换、插入域代码等功能,还涉及Word转PDF及格式互转,最后通过实例展示了查找替换与插入域代码的应用。

诸神缄默不语-个人技术博文与视频目录

视频教程:Python通过win32com库操作Word教程_哔哩哔哩_bilibili

如果需要原Jupyter notebook文件和用作示例的图片、文档,可以联系我。

引言

在 Python 生态中,操作 Word 文档的库有不少,比如 python-docx 主要处理 .docx 格式,而 win32com(即 pywin32)则提供了更为底层的控制能力——它直接调用微软 Office 的 COM 接口,这意味着你的 Word 软件能做什么,win32com 就能做什么。不仅可以读写文本,还能操作表格、图表、域代码、目录、格式转换,甚至执行查找替换等复杂任务。

不过,使用它也有一些前提和限制:

  • 只能在 Windows 系统上运行,并且必须已安装 Microsoft Word(WPS 或其他打开 Word 的软件不行)。
  • 默认情况下,代码是单线程的。
  • 操作完成后,务必记得关闭 Word 客户端doc.Close()word.Quit()),否则 Word 进程会一直留在后台,需要手动从任务管理器结束。

win32com 其实是一个通用 COM 客户端,不仅能操作 Word,还能操作 Excel、PPT、Outlook 等微软软件。本文只聚焦于 Word 的操作。

通过python-docx、docxtpl、Composer库处理Word文档的教程请参考:Python处理Word文档完全指南:从基础到进阶

安装

pip install pywin32

如果遇到常数(constants)加载异常(例如无法使用 constants.wdReplaceAll),可以尝试强制重新生成缓存:

import win32com.client as win32
word = win32.gencache.EnsureDispatch('Word.Application')  # 替换win32.Dispatch()接口

或者手动删除缓存文件夹(通常在 %temp%\gen_py 下,例如 C:\Users\用户名\AppData\Local\Temp\gen_py)。

基础概念

在深入代码之前,先了解几个核心对象:

对象 说明
Application Word 应用程序本身,通过 win32.Dispatch 获得
Document 代表一个打开的文档,通过 Documents.AddDocuments.Open 获取
Selection 当前光标选中的区域(或光标位置)
Range 文档中的一个连续区域(可以不是选中状态)
Paragraph 段落,由回车符分隔
Font / ParagraphFormat 字体和段落格式

1. 新建文档并写入文字

使用 Range 对象

import win32com.client as win32

word = win32.Dispatch("Word.Application")
word.Visible = True   # True 会显示 Word 界面(但很快消失)

doc = word.Documents.Add()
range_obj = doc.Range(0, 0)
range_obj.InsertAfter("Hello World from Python!")

# 注意:必须使用绝对路径,否则会保存到 Word 的默认文件夹
doc.SaveAs(r"D:\your_path\test.docx")
doc.Close()
word.Quit()

使用 Selection 对象(模拟光标)

word = win32.Dispatch("Word.Application")
word.Visible = False

doc = word.Documents.Add()
selection = word.Selection

selection.TypeText("Hello, World!")
selection.TypeParagraph()          # 换行(新段落)
selection.TypeText("这是第二行")

doc.SaveAs(r"D:\your_path\test.docx")
doc.Close()
word.Quit()

注意Range 是一个独立区域,不依赖光标;Selection 则代表当前光标位置,常用于模拟用户操作。

2. 打开文档,读取内容并追加文字

word = win32.Dispatch("Word.Application")
word.Visible = False

doc = word.Documents.Open(r"D:\your_path\test.docx")

# 遍历所有段落打印内容
for paragraph in doc.Paragraphs:
    print(paragraph.Range.Text)

# 在文档末尾追加内容
doc.Content.InsertAfter("\n这是新增的内容")

doc.Close()
word.Quit()

注意:直接使用 doc.Content.Text 获取全文有时会返回异常结果(如只得到这是第二行, World!),所以推荐遍历段落。

3. 设置字体与段落格式

误区:使用 Selection 设置字体无效

selection = word.Selection

# 字体设置无效
selection.Font.Name = "微软雅黑"
selection.Font.Size = 16
selection.Font.Bold = True
selection.Font.ColorIndex = 6      # 红色

# 段落设置有效
selection.ParagraphFormat.Alignment = 1   # 居中(0左 1中 2右 3两端)
selection.ParagraphFormat.LineSpacingRule = 0  # 单倍行距

原因:Selection 只是一个点,设置字体需要作用于一个区域。

正确方法:使用 Range 设置整个文档

range_obj = doc.Content
range_obj.Font.Name = "微软雅黑"
range_obj.Font.Size = 16
range_obj.Font.Bold = True
range_obj.Font.ColorIndex = 6
range_obj.ParagraphFormat.Alignment = 1
range_obj.ParagraphFormat.LineSpacingRule = 0

设置标题样式

range_obj = doc.Range(0, 0)
range_obj.Text = "第一章 概述"
range_obj.Style = doc.Styles("标题 1")   # 英文版可能是 "Heading 1"

4. 插入表格

range_obj = doc.Content
range_obj.Collapse(0)          # 0 折叠到末尾,1 折叠到开头

table = doc.Tables.Add(range_obj, NumRows=3, NumColumns=3)

# 单元格索引从 1 开始
table.Cell(1,1).Range.Text = "姓名"
table.Cell(1,2).Range.Text = "年龄"
table.Cell(1,3).Range.Text = "结果"

table.Cell(2,1).Range.Text = "张三"
table.Cell(2,2).Range.Text = "25"
table.Cell(2,3).Range.Text = "合格"

5. 查找与替换

简单替换(全文匹配)

find = word.Selection.Find
find.Text = "{
   {name}}"
find.Replacement.Text = "张三"
find.Execute(Replace=2)          # Replace=2 表示全部替换

处理缓存异常问题

缓存异常的显著表现是无法导入 constants ,同时查找和替换功能也会出现异常。可以显式设置所有参数来解决问题:

WD_FIND_CONTINUE = 1   # 继续查找
WD_REPLACE_ALL = 2     # 全部替换

rng = doc.Content
for old, new in [("{
   {name}}", "张三"), ("{
   {date}}", "2026-02-26")]:
    rng.Find.Execute(
        old, False, False, False, False, False,
        True, WD_FIND_CONTINUE, False, new, WD_REPLACE_ALL
    )
    rng = doc.Content   # 重新获取 Range,避免被移动

6. 插入图片

range_obj = doc.Content
range_obj.Collapse(0)   # 移动到末尾

doc.InlineShapes.AddPicture(
    r"D:\your_path\pic1.jpeg",
    False, True, range_obj
)

7. 更新目录

for toc in doc.TablesOfContents:
    toc.Update()

8. Word 转 PDF 及 doc/docx 互转

doc.ExportAsFixedFormat(
    OutputFileName=r"D:\your_path\test.pdf",
    ExportFormat=17      # 17 代表 PDF;16 代表 docx;0/1 代表 doc
)

笔者曾基于此功能开发过一个桌面工具,支持 Word/PDF 互转及 Excel 格式互转,详情参考:如何用Python处理文件:Word导出PDFdoc / docx互相转换

9. 插入域代码:以日期域为例

range_obj = doc.Content
range_obj.Collapse(0)

field = doc.Fields.Add(
    Range=range_obj,
    Type=31               # wdFieldDate
)

# 等价写法(插入空域,再指定代码)
# field = doc.Fields.Add(
#     Range=range_obj,
#     Type=constants.wdFieldEmpty,
#     Text="DATE  \\* MERGEFORMAT"
# )

10. 实例:将纯文本图标签替换为 SEQ 域

原始文档:包含“图 1”、“图 2”等纯文本
目标:替换为域代码 图 { SEQ 图 \* ARABIC },实现自动编号。

word = win32.gencache.EnsureDispatch('Word.Application')
word.Visible = False
doc = word.Documents.Open(r"D:\your_path\instance1.docx")

search_range = doc.Range()
search_range.Find.Text = "图 [0-9]{1,}"
search_range.Find.Wrap = 0                 # wdFindStop,不循环
search_range.Find.MatchWildcards = True    # 通配符匹配

found = search_range.Find.Execute()
while found:
    insert_point = search_range.Duplicate   # 复制当前 Range
    insert_point.Delete()                    # 删除原文本
    insert_point.InsertAfter("图 ")           # 插入“图 ”
    insert_point.Collapse(Direction=0)        # 折叠到末尾

    # 插入 SEQ 域
    seq_code = 'SEQ 图 \\* ARABIC'
    doc.Fields.Add(insert_point, -1, seq_code, False)  # -1 代表 wdFieldEmpty

    search_range.Collapse(Direction=0)
    found = search_range.Find.Execute()

doc.Fields.Update()
doc.SaveAs(r"D:\your_path\test.docx")
doc.Close()
word.Quit()

11. 复杂实例:带章节号的图标签(如 图 1-1、图 1-2)

原始文档:包含“图 1-1”、“图 1-2”等纯文本
目标:替换为 图 { STYLEREF 1 \s }-{ SEQ 图 \* ARABIC \s 1 },其中章节号来自标题1(一级标题)的编号。

word = win32.Dispatch("Word.Application")
word.Visible = False
doc = word.Documents.Open(r"D:\your_path\instance2.docx")

search_range = doc.Range()
search_range.Find.Text = "图 [0-9]{1,}-[0-9]{1,}"
search_range.Find.Wrap = constants.wdFindStop
search_range.Find.MatchWildcards = True

found = search_range.Find.Execute()
while found:
    insert_point = search_range.Duplicate
    insert_point.Delete()
    insert_point.InsertAfter("图 ")
    insert_point.Collapse(Direction=constants.wdCollapseEnd)

    # 插入 STYLEREF 域
    styleref_code = 'STYLEREF 1 \\s'
    field_styleref = doc.Fields.Add(insert_point, constants.wdFieldEmpty, styleref_code, False)
    field_styleref.Update()

    # 将光标移动到域之后
    field_styleref.Select()
    word.Selection.Collapse(Direction=constants.wdCollapseEnd)
    insert_point = word.Selection.Range.Duplicate

    # 插入连字符
    insert_point.InsertAfter("-")
    insert_point.Collapse(Direction=constants.wdCollapseEnd)

    # 插入 SEQ 域
    seq_code = 'SEQ 图 \\* ARABIC \\s 1'
    doc.Fields.Add(insert_point, constants.wdFieldEmpty, seq_code, False)

    search_range.Collapse(Direction=constants.wdCollapseEnd)
    found = search_range.Find.Execute()

doc.Fields.Update()
doc.SaveAs(r"D:\your_path\test.docx")
doc.Close()
word.Quit()

关键点:

  • 使用 Duplicate 复制 Range,避免原对象被后续操作改变。
  • 插入域后需要先更新域(Update()),然后选中它再折叠,才能准确定位到域之后的位置。
  • 这些技巧在插入复杂域时非常重要。

总结

win32com 是操作 Word 的强大工具,几乎可以实现 VBA 能做的所有事情。本文涵盖了从新建文档、格式设置、表格、查找替换、图片、目录、格式转换到域代码操作等常见需求。虽然它有平台限制(仅 Windows + 已安装Word软件),但对于需要深度控制 Word 文档的自动化任务来说,它是不可或缺的利器。

相关文章
|
24天前
|
Web App开发 数据采集 前端开发
如何在VSCode中查看、转换markdown文件:使用MPE(Markdown Previe Enhanced)插件
本文介绍了在VSCode中使用MPE插件处理Markdown文件的方法。主要内容包括:1)MPE插件的安装;2)查看Markdown渲染效果的两种方式(内置快捷键和MPE右键预览);3)Markdown文件转换功能,详细讲解了导出HTML(离线/在线模式)、PDF(Chrome/Prince/Pandoc三种方式)和Word的操作步骤及注意事项。文章还提供了相关软件的安装指南和常见问题解决方案,帮助用户更好地使用MPE插件进行Markdown文档处理。
如何在VSCode中查看、转换markdown文件:使用MPE(Markdown Previe Enhanced)插件
|
25天前
|
边缘计算 安全 网络协议
AIWCLOUD:免备案高防CDN,抗投诉,大陆节点免备,在跨国企业混合办公场景下
后疫情时代,跨国企业混合办公面临跨境延迟、未备案域名访问受限及VPN安全隐患等痛点。本文介绍一种“免备案CDN”架构:融合边缘零信任接入(ZTNA)、动态端口敲门、SAP/RDP协议优化、HTTP/3加速、域名分片合规回源与实时数据脱敏,构建安全、合规、高性能的全球数字走廊。(239字)
185 4
|
23天前
|
人工智能 弹性计算 API
阿里云轻量应用服务器低成本部署OpenClaw方案:2核2G38元,2核4G199元,全球多地域可选
2026年阿里云轻量应用服务器低成本部署OpenClaw AI助理的方案:用户可通过每天10:00和15:00的限量抢购活动,以38元/年(2核2G/40G云盘)或9.9元/月、199元/年(2核4G/50G云盘)的价格入手服务器,预装OpenClaw镜像实现分钟级一键部署,免代码上手。部署后可通过Web UI或飞书、钉钉、QQ、企业微信等IM工具与AI智能体交互,并支持扩展Skill和自定义RPA流程。方案覆盖个人博客、AI应用开发等场景,大幅降低了AI Agent的技术与资金门槛,是低成本拥抱AI智能体的实用路径。
|
14小时前
|
数据采集 存储 算法
视频 RAG 中分块策略:基于停顿、滑动窗口与基于 LLM 的方法
本文探讨视频RAG中的核心挑战——如何为无时间结构的视频转录文本设计有效分块策略。对比传统文本分块,提出基于停顿、重叠窗口、递归切分及LLM驱动的主题分块四层方案,实现细粒度检索与全局理解兼顾,提升视频内容检索准确性与上下文完整性。
133 13
视频 RAG 中分块策略:基于停顿、滑动窗口与基于 LLM 的方法
|
14小时前
|
机器学习/深度学习 数据采集 人工智能
田间杂草检测数据集分享(适用于YOLO系列深度学习分类检测任务)
本数据集含4000张真实农田图像(小麦/玉米/水稻田),YOLO格式标注杂草目标,覆盖多天气、光照与视角,适用于YOLO系列等目标检测模型训练,助力智能除草与精准农业研究。(239字)
204 16
|
14小时前
|
API
阿里云微服务引擎 MSE 及 API 网关 2026 年 5 月产品动态
阿里云微服务引擎 MSE 及 API 网关 2026 年 5 月产品动态。
132 10
|
14小时前
|
自然语言处理 前端开发 安全
2026 世界杯钓鱼即服务平台攻击机理与防御体系研究
2026世界杯前夕,“Ghost Stadium”中文钓鱼即服务平台发动大规模攻击,涉案4.7–10亿美元,受害超4.7万人,窃取FIFA凭证2500+条,注册恶意域名超4000个。该平台采用React+Layui实现像素级克隆、SSO模拟与多语言适配,构建覆盖社交广告、搜索、IM的立体攻击网络。本文基于实证分析,提出检测、响应、溯源、治理闭环防御体系,强调跨机构协同与动态对抗。(239字)
144 10
|
14小时前
|
人工智能 缓存 弹性计算
阿里云服务器2核4G5M199元解析:独享型u1实例,性能、适用场景、购买和续费规则介绍
阿里云通用算力型u1实例(ecs.u1-c1m2.large)2核4G、5M带宽、80G ESSD Entry云盘,活动特惠价仅199元/年(官网价3498.36元),企业新老用户同享,续费同价至2027年3月31日,每人限购1台。该实例采用独享型架构,搭载Intel至强可扩展处理器,内网带宽1Gbit/s、收发包30万PPS、云盘IOPS 1万,性能稳定,适合企业官网、中小Web应用、轻量数据库及开发测试等场景。
|
14小时前
|
安全 JavaScript 前端开发
《ZAKU渗透论:卓伊凡的2026渗透工程》第四章:Web攻击原理(下)——XSS、CSRF、文件上传漏洞
本章详解XSS、CSRF与文件上传三大Web漏洞:XSS通过注入恶意脚本窃取Cookie;CSRF伪造已登录用户请求执行非自愿操作;文件上传漏洞则因校验缺失致服务器被控。三者共性——过度信任用户输入。(239字)
249 10
|
14小时前
|
人工智能 安全 关系型数据库
RDS Agent可观测能力正式邀测!全面支持Qoder、Codex、Claude Code、OpenClaw等主流研发Agent
阿里云RDS Agent可观测平台正式发布!面向Qoder、Codex等多类AI Agent,提供统一接入、Token/成本归因、ROI分析、风险回溯与全链路Trace下钻能力,基于RDS MySQL+DuckDB列式分析底座,助力团队从“使用Agent”迈向“治理Agent”。
171 6