news 2026/9/4 4:40:12

Python办公自动化实战:Word文档批量生成、修改与格式转换

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python办公自动化实战:Word文档批量生成、修改与格式转换

这次我们来做一个 Python 办公自动化实战案例,重点放在Word 文档读写这一块。

课程编号是py100--lv2-085,对应的是 Python 入门 100 天中的进阶第四类任务:用脚本批量生成、修改和转换 Word 文档。实际工作里很多重复劳动都集中在 Word 上,比如每周写周报、批量生成报名表、处理招投标文件里的格式、把 docx 批量转成 PDF。手动做一遍两遍还行,做到第十遍就会想:能不能让 Python 直接干完。

这篇文章不聊概念,直接演示三套能力:用python-docx生成结构化文档、用pywin32调用本地 Word 完成格式转换、用docxcompose或标准库思路做批量合并与模板填充。如果你正在学习 Python 办公自动化、或手头刚好有一批 Word 文档要批量处理,这篇可以直接收藏并按步骤操作。

1. 核心能力速览

在写代码前,先把这节课涉及的技术栈和能力边界讲清楚。

能力项说明
项目类型Python 办公自动化实战教程(Word 文档处理方向)
核心依赖python-docxpywin32pdf2docxdocxcompose
可处理任务新建 word、批量生成 word、修改已有 word、docx 批量转 PDF、PDF 转 docx
推荐环境Windows 10/11 + Python 3.9 及以上;macOS/Linux 可运行 python-docx,但 win32com 仅限 Windows
显存需求不需要 GPU,纯 CPU 即可
启动方式命令行运行 Python 脚本
是否支持批量任务支持,遍历文件夹即可实现批量处理
是否提供接口 APIpython-docx 是第三方库,可直接集成到 Flask/FastAPI 服务中
适合人群Python 初学者、办公自动化方向学习者、有批量文档处理需求的人

注意一点:python-docx不依赖本地安装 Microsoft Word,它是纯 Python 解析.docx文件;而pywin32这种方式必须在本机安装 Word 或 WPS 组件才能调用。实际项目中两种思路经常混用。

2. 适用场景与使用边界

2.1 这个工具适合谁

  • 每月要出 30 份格式相同的项目报告,手动改标题、改日期、改姓名,效率太低;
  • 人事或教务场景,需要根据 Excel 名单批量生成录用通知书、报名表、成绩单;
  • 需要在文档交付前把一批 docx 统一另存为 PDF,并且统一页边距、字体和页码;
  • 想把零散文档内容合并到一个 Word 文件里做归档;
  • 正在做一件事:避免打开 Word 手动复制粘贴,用几行代码一步到位。

2.2 不适合什么场景

python-docx不是万能的。它不能处理.doc老格式,也不能执行 Word 里复杂的宏逻辑。要解析老式.doc,需要先另存为.docx,或者使用 win32com 调用 Word 完成转换。

另外,如果文档里有复杂的公式、文本框、嵌入对象、复杂的交叉引用,用python-docx修改时容易破坏排版。这种场景更适合用 win32com 在 Word 应用内部操作。

2.3 使用边界与合规提醒

自动化处理 Word 本身没有安全风险,但要注意两点:

  1. 处理他人提供的文档前,先确认来源合法,涉及个人信息的报名表、成绩单、合同模板要做好脱敏处理;
  2. 脚本生成的文档如果要商用在外部发布,必须复核内容和格式是否合规;
  3. 不要编写宏代码去绕过文档保护或密码机制,这属于破坏访问控制,不符合安全边界。

3. 环境准备与前置条件

3.1 安装 Python

到 Python 官网下载 3.9 以上版本,安装时勾选Add Python to PATH。安装完成后,打开终端或命令提示符,输入以下命令验证:

python --version pip --version

如果提示命令不存在,说明没有加到 PATH,需要手动把 Python 安装目录加入系统环境变量。

3.2 安装依赖库

本项目核心依赖共四个,按需安装:

pip install python-docx pywin32 pdf2docx docxcompose

四个库的作用:

库名作用
python-docx操作 .docx 文件,创建文档、添加段落、表格、图片,修改样式
pywin32在 Windows 上调用本机 Word 应用,实现 doc/docx 转 PDF、批量另存为
pdf2docx将 PDF 文件解析并生成 Word 文档
docxcompose合并多个 docx 文件,能够保留编号列表和连续页码

如果你只在 Linux 服务器上用 python-docx,不需要 pywin32:

pip install python-docx

3.3 准备测试文档

建议在本地建一个专门目录:

D:/word_auto/ ├─ input/ # 放待处理的文档 ├─ output/ # 输出结果目录 ├─ template/ # 模板文档目录 └─ scripts/ # Python脚本目录

用这个目录规范学习阶段的所有测试。

3.4 验证环境是否正确

安装完成后,先运行一个最小脚本,确认库能正常导入:

from docx import Document doc = Document() doc.add_paragraph("测试段落") doc.save("D:/word_auto/output/test.docx") print("环境正常,文件已生成")

如果终端没有报错,说明 python-docx 已经可用了。

4. 创建 Word 文档的三种基础写法

这一节内容是整个实战的根基。先理解 python-docx 最核心的三个对象:DocumentParagraphTable

4.1 添加标题与段落

创建文档并设置标题:

from docx import Document from docx.shared import Pt, RGBColor from docx.enum.text import WD_ALIGN_PARAGRAPH doc = Document() # 添加标题 doc.add_heading("项目周报", level=1) # 添加普通段落 p = doc.add_paragraph("本周完成以下工作:") p.alignment = WD_ALIGN_PARAGRAPH.LEFT # 添加带格式的段落 run = doc.add_paragraph().add_run("这是加粗红色文字") run.bold = True run.font.size = Pt(14) run.font.color.rgb = RGBColor(255, 0, 0) doc.save("D:/word_auto/output/test_format.docx")

理解run很重要:它不是整个段落,而是段落中拥有相同格式的一段文本。你要修改某几个字的字体颜色,就操作 run。

4.2 插入表格

创建三行四列的表格,并写入数据:

from docx import Document from docx.shared import Pt doc = Document() table = doc.add_table(rows=3, cols=4) table.style = "Table Grid" data = [ ["姓名", "部门", "本周任务", "状态"], ["张三", "技术部", "完成接口开发", "已完成"], ["李四", "产品部", "输出需求文档", "进行中"] ] for row_idx, row_data in enumerate(data): for col_idx, cell_text in enumerate(row_data): cell = table.cell(row_idx, col_idx) cell.text = str(cell_text) doc.save("D:/word_auto/output/test_table.docx")

这里有一个常见坑:如果不指定table.style,表格在生成的 docx 里可能看起来没有边框线,打印或预览时像普通文本。设成"Table Grid"是带全边框的最常用样式。

4.3 插入图片并调整尺寸

from docx import Document from docx.shared import Cm doc = Document() doc.add_heading("图片附页", level=2) pic = doc.add_picture("D:/word_auto/input/chart.png", width=Cm(14)) doc.save("D:/word_auto/output/test_picture.docx")

注意:插入图片时传入的是本地路径,图片格式支持 png、jpg、gif 等常见格式。宽度单位使用Cm(14)表示 14 厘米,如果不指定长度,图片按原始像素大小插入,可能超出页面范围。

5. 实战:模板批量生成报名表

进入真正的办公自动化环节。最常见的重复劳动场景是:已经有 Excel 名单,需要给每个人生成一份格式相同的 Word 表。

5.1 需求拆解

  • 输入:Excel 名单,包含姓名、性别、部门、职位
  • 输出:每人一份 Word 报名表,文件名命名为“姓名_报名表.docx”
  • 格式:固定标题、表格有固定表头、个人信息从上到下排列

5.2 打开 Excel 读取名单

先读取 Excel 名单:

import pandas as pd df = pd.read_excel("D:/word_auto/input/roster.xlsx") print(df.head())

处理 Excel 时用 pandas 最方便。如果名单量很少,也可以直接用 csv 模块。

5.3 生成报名表主代码

import os from docx import Document from docx.shared import Pt, Cm from docx.enum.table import WD_ALIGN_VERTICAL import pandas as pd def create_registration_form(data: dict, output_path: str): doc = Document() # 文档标题 title = doc.add_heading("报名登记表", level=0) title.alignment = 1 # 居中 # 个人信息表格 table_data = [ ["姓名", data["姓名"], "性别", data["性别"]], ["部门", data["部门"], "职位", data["职位"]], ["联系电话", data["电话"], "邮箱", data["邮箱"]], ["备注", "", "", ""], ] table = doc.add_table(rows=len(table_data), cols=4) table.style = "Table Grid" for row_idx, row_data in enumerate(table_data): for col_idx, cell_text in enumerate(row_data): cell = table.cell(row_idx, col_idx) cell.text = str(cell_text) cell.vertical_alignment = WD_ALIGN_VERTICAL.CENTER # 设置列宽 for row in table.rows: row.cells[0].width = Cm(2.5) row.cells[1].width = Cm(4.5) row.cells[2].width = Cm(2.5) row.cells[3].width = Cm(5.5) doc.save(output_path) print(f"已生成: {output_path}") # 主流程 df = pd.read_excel("D:/word_auto/input/roster.xlsx") os.makedirs("D:/word_auto/output/forms", exist_ok=True) for _, row in df.iterrows(): data = { "姓名": row["姓名"], "性别": row["性别"], "部门": row["部门"], "职位": row["职位"], "电话": row["电话"], "邮箱": row["邮箱"], } output_path = f"D:/word_auto/output/forms/{row['姓名']}_报名表.docx" create_registration_form(data, output_path)

以上脚本执行后,output/forms 目录下会生成若干 Word 文件。判断标准很简单:文件是否生成、表格里姓名电话是否正确、文件名是否和名单对应。

5.4 增强:自动调整单元格字体

如果希望每个单元格里的字号统一为 11 磅,可以增加单元格遍历逻辑:

for row in table.rows: for cell in row.cells: for paragraph in cell.paragraphs: for run in paragraph.runs: run.font.size = Pt(11)

这段逻辑要放在填充表格之后、保存之前。

5.5 注意事项

python-docx 没有内置“查找并替换宏”这种一键操作。当你批量生成时,一定要先拿一个人的数据跑通脚本,再整个文件夹跑,避免生成 50 份错误文件再去改。

6. 修改已有 Word 文档:批量替换文本与样式

实际办公中,很多需求是“把这段文字里的公司名改成另一个公司名”“把日期改成最新日期”“把标题字号统一为 16 磅”。这种场景处理量不大,但手动逐个打开替换同样繁琐。

6.1 批量替换段落文本

python-docx 不能直接做类似 ctrl+H 的全局替换,但可以通过遍历段落中的 run 来实现。这里有三种替换粒度:

  • 直接替换段落全部文字,会丢失原有格式;
  • 逐个 run 替换精确文本,能保留大部分格式;
  • 精确到指定 run 内的文字,通用性最强。

最常用的场景是精确替换段落文本:

from docx import Document def replace_paragraph_text(doc, old_text, new_text): """遍历所有段落,如果段落文本等于旧文本,则替换""" for paragraph in doc.paragraphs: if old_text in paragraph.text: # 保留第一个run的格式,清空其他run for run in paragraph.runs: run.text = "" paragraph.runs[0].text = paragraph.text.replace(old_text, new_text) print(f"替换段落: {old_text} -> {new_text}") doc = Document("D:/word_auto/input/old_report.docx") replace_paragraph_text(doc, "北京某某科技有限公司", "上海某某信息科技有限公司") doc.save("D:/word_auto/output/new_report.docx")

注意这里的坑:如果直接把paragraph.text用字符串方法替换,虽然看似只改文字,但原来这段里被切分成多个 run 的加粗、颜色信息会丢失。把旧文本所在的每个 run 分别替换才更安全。

6.2 精确到 run 的替换函数

为了保留被替换部分周围的格式,可以改进成逐 run 匹配:

from docx import Document def replace_in_runs(doc, old_text, new_text): count = 0 for paragraph in doc.paragraphs: for run in paragraph.runs: if old_text in run.text: run.text = run.text.replace(old_text, new_text) count += 1 # 表格中的段落也要处理 for table in doc.tables: for row in table.rows: for cell in row.cells: for p in cell.paragraphs: for run in p.runs: if old_text in run.text: run.text = run.text.replace(old_text, new_text) count += 1 print(f"共替换 {count} 处") return doc

这个函数是对 word 自动化很有用的一个工具函数,可以放在自己的公共模块里。

6.3 修改表格样式与列宽

处理批量表格的格式时,需要遍历每个表格的每一行。

from docx import Document from docx.shared import Cm doc = Document("D:/word_auto/input/need_change.docx") for table in doc.tables: # 设置所有列宽 for row in table.rows: row.cells[0].width = Cm(2) row.cells[1].width = Cm(6) # 表头加粗 for cell in table.rows[0].cells: for paragraph in cell.paragraphs: for run in paragraph.runs: run.bold = True doc.save("D:/word_auto/output/table_changed.docx")

热词里提到“poi设置word表格单元格宽度”,对应到 Java 是 POI,Python 里调整列宽就是通过row.cells[i].width设置。要注意 Word 实际渲染时会综合每列所有单元格的宽度,最好统一设置每一列的单元格宽度。

6.4 批量操作文件夹中的所有 docx

实现批量任务的核心是遍历文件夹:

import os from docx import Document input_dir = "D:/word_auto/input" output_dir = "D:/word_auto/output" for filename in os.listdir(input_dir): if filename.lower().endswith(".docx"): input_path = os.path.join(input_dir, filename) output_path = os.path.join(output_dir, filename) doc = Document(input_path) replace_in_runs(doc, "腾讯", "某某企业") doc.save(output_path) print(f"处理完成: {filename}")

批量任务务必加日志,把处理过的文件名打印出来,方便排查。

7. win32com:调用 Word 完成 doc/docx 互转与 PDF 输出

python-docx 是“不启动 Word 应用”地解析文件,功能局限在于无法处理.doc老格式、无法读取页面设置里的某些复杂属性。如果需要调用 Word 本身的另存为、打印、合并功能,在 Windows 上可以用 pywin32 连接 COM 组件。

7.1 win32com 的适用场景

  • .doc转成.docx,再用 python-docx 后续处理;
  • 把 docx 批量转 PDF;
  • 打开文档后调整页边距、页眉页脚;
  • 获取 Word 文档真实的页数,按页拆分文档;
  • 执行 Word 自带的查找替换功能。

7.2 单文件 docx 转 PDF

import os from win32com.client import DispatchEx def docx_to_pdf(input_docx, output_pdf): # DispatchEx 比 Dispatch 更安全,避免引用已有实例 word = DispatchEx("Word.Application") word.Visible = False # 不显示Word界面 word.DisplayAlerts = 0 # 不显示弹窗 try: doc = word.Documents.Open(os.path.abspath(input_docx)) doc.SaveAs(os.path.abspath(output_pdf), FileFormat=17) # 17 是 PDF 格式代码 doc.Close() print(f"转换成功: {output_pdf}") except Exception as e: print(f"转换失败: {e}") finally: word.Quit()

调用示例:

docx_to_pdf("D:/word_auto/input/old_report.docx", "D:/word_auto/output/old_report.pdf")

注意:FileFormat=17是 Word 的 PDF 导出格式代码,这个值是稳定的,不会变。

7.3 批量转换文件夹内所有 Word 文档为 PDF

import os from win32com.client import DispatchEx input_dir = "D:/word_auto/input" output_dir = "D:/word_auto/output/pdf_batch" os.makedirs(output_dir, exist_ok=True) word = DispatchEx("Word.Application") word.Visible = False word.DisplayAlerts = 0 try: for filename in os.listdir(input_dir): if filename.lower().endswith((".docx", ".doc")): input_path = os.path.abspath(os.path.join(input_dir, filename)) base_name = os.path.splitext(filename)[0] output_path = os.path.join(output_dir, base_name + ".pdf") doc = word.Documents.Open(input_path) # 统一去除只读或修改权限限制 doc.ReadOnlyRecommended = False doc.SaveAs(os.path.abspath(output_path), FileFormat=17) doc.Close() print(f"已转换: {filename}") finally: word.Quit()

7.4 win32com 的批量处理注意事项

每个文件转换之间留出时间:批量转换十几份没问题,上百份时 Word COM 进程可能卡死。建议在每份文档处理后加入:

import time time.sleep(0.5)

观察任务管理器:Win32com 方式会启一个WINWORD.EXE进程。如果脚本异常退出,这个进程可能残留,导致后续文件打开时提示“文件正在使用”。遇到这种情况,在任务管理器中结束WINWORD.EXE或多出的 Python 进程即可。

7.5 用 win32com 清空页眉页脚或重置样式

在某些版本更新或模板切换场景,旧的页眉页脚需要统一清理。COM 方式路径很简单:

from win32com.client import DispatchEx word = DispatchEx("Word.Application") word.Visible = False doc = word.Documents.Open("D:/word_auto/input/old_header.docx") for section in doc.Sections: header = section.Header header.Range.Delete() doc.Save() doc.Close() word.Quit()

这里不建议用 python-docx 处理页眉,不是做不到,而是页眉在不同节之间链接关系比较复杂,COM 操作更符合人类使用 Word 的逻辑。

8. PDF 转 Word:使用 pdf2docx

热词中“pdf转word”出现频率很高,正好补充这一节。

pdf2docx可以把 PDF 文件解析并转成 Word 文档,适合处理文字型和简单表格型 PDF,不适合扫描件(扫描件需要 OCR 配合)。

8.1 单文件转换

from pdf2docx import Converter pdf_file = "D:/word_auto/input/paper.pdf" docx_file = "D:/word_auto/output/paper.docx" cv = Converter(pdf_file) cv.convert(docx_file) cv.close() print("转换完成")

8.2 批量转换目录下所有 PDF

import os from pdf2docx import Converter input_dir = "D:/word_auto/input" output_dir = "D:/word_auto/output/docx_from_pdf" os.makedirs(output_dir, exist_ok=True) for filename in os.listdir(input_dir): if filename.lower().endswith(".pdf"): pdf_path = os.path.join(input_dir, filename) docx_name = os.path.splitext(filename)[0] + ".docx" docx_path = os.path.join(output_dir, docx_name) cv = Converter(pdf_path) cv.convert(docx_path, start=0, end=None) cv.close() print(f"已转换: {filename}")

8.3 当前转换局限

PDF 转 Word 后的排版能否保持完美,主要看源 PDF 是否使用嵌入字体、是否有复杂的图文混排。如果 PDF 里只有清晰文字,转换结果很好;如果含有大量图片、旋转文字、艺术字,转换后需要校对版面。

重要提醒:只转换你自己拥有版权或获准使用的 PDF 文件,不要拿自动化工具批量处理他人受版权保护的书籍和论文。

9. 批量合并多个 Word 文档

如果多个 word 章节文件需要合成一个新的 word 文件,可以用 docxcompose 完成。

from docxcompose.composer import Composer from docx import Document master_doc = Document("D:/word_auto/input/chapter_1.docx") composer = Composer(master_doc) files_to_append = [ "D:/word_auto/input/chapter_2.docx", "D:/word_auto/input/chapter_3.docx", ] for file_path in files_to_append: append_doc = Document(file_path) composer.append(append_doc) composer.save("D:/word_auto/output/merged.docx")

使用 docxcompose 的好处是它会尽量保留原文档的编号连续性和分页符处理,比直接用 python-docx 的底层 body XML 合并靠谱。

如果只需要简单地把几个文档的内容堆到一个文档里,也可以自己写纯 python-docx 版本,但处理页码格式、列表编号时会比较麻烦。工程上优先推荐 docxcompose。

10. 资源占用与性能观察

这一节重点回答“脚本跑的时候占多少资源、会不会卡顿”。

10.1 python-docx 的资源占用

python-docx不启动 Word 进程,它以纯 Python 方式读取 zip 包中的 XML,因此性能瓶颈集中在 CPU 和内存上。生成一份 10 页、带 5 个表格的文档,内存占用通常在几十到几百 MB 之间,具体看图片数量。批量处理几千个文件时,内存会累积,建议每处理完一个文件后调用 save,并让变量回收。

10.2 win32com 的资源占用

win32com 启动 Word 应用,会看到WINWORD.EXE进程,内存一般在 100 到 300 MB 左右。这个不是 Python 能直接控制的,它属于 Word 本身的资源占用。批量转换多份文档时,如果发现 Word 进程占用持续飙高,可以每处理完 N 份后重启一次 Word 进程。

处理大量带图片的 docx 时,优先推荐纯 python-docx 处理,不启动 Word,速度更快。

10.3 PDF 转换的资源占用

pdf2docx 是 CPU 密集任务。页数越多、图片越多,耗时越长。转换一本 200 页的 PDF 可能需要几十秒甚至几分钟,不是脚本卡死,是计算量确实大。遇到大文件先转 5 页测试,确认排版符合预期再全量转。

10.4 降低资源占用的通用手段

  • 减少不必要的循环嵌套;
  • 每处理一个文件释放一次引用;
  • 在循环中不要频繁打开同一个文档;
  • 批量任务用日志记录进度,方便中途中断后继续;
  • 大批量处理时不要一次性把所有文件读入内存列表,使用os.scandir或生成器逐条遍历。

11. 常见问题与排查方法

问题现象可能原因排查方式解决方案
导入docx报 ModuleNotFoundErrorpython-docx 未安装执行pip list查看依赖执行pip install python-docx
生成的 Word 打开提示“文件已损坏”文档被错误路径保存,或 Word 正在占用源文件查看保存路径和权限在非系统目录路径下重新保存;关闭 Word 中的同名文件
python-docx 打开.doc失败库不支持.doc老格式检查文件后缀用 win32com 将.doc.docx
表格添加后预览没有边框未指定表格样式检查代码是否设置table.style添加table.style = "Table Grid"
替换文字后格式丢失对整个段落文本重新赋值导致 run 被合并检查替换逻辑改为在 run 级别替换,保留格式
win32com 找不到Word.Application没有安装 Word/WPS,或 COM 注册失败检查电脑是否安装 Office安装 WPS 或 Office;确认 Office 是完整安装而非商店精简版
批量转换时卡在某个文件个别文档有破损或复杂对象查看日志停在哪一个文件先跳过该文件,手动打开另存一次后重新处理
生成的 PDF 页数和 Word 不一致字体缺失导致分页变化检查系统中文字体安装情况安装常用中文字体;在 Word 中设置默认字体后重新转换
pdf2docx 转换时抛ImportErrorPDF 里的对象无法解析查看错误具体页面对问题 PDF 做 OCR 预处理或调整转换页码范围
脚本运行后看不到输出终端缓冲或 print 被吞重定向输出到日志文件使用logging模块输出到文件

排查流程一般按顺序做:确认 Python 版本与依赖、确认文件路径、确认文档格式、看报错堆栈、单文件调试、再批量执行。

排查的第一行代码永远是先打印路径:

import os print(os.path.exists("D:/word_auto/input/old_report.docx")) print(os.path.abspath("D:/word_auto/input/old_report.docx"))

不要假设路径对,直接把路径是否存在打出来是最快的排查方式。

12. 一键封装为带界面的小工具

热词中大量出现“python 转 exe 文件”,这说明很多读者不只想要脚本,而是想给同事做一个 windows 双击能运行的批量转换工具。这里给一个轻量方案。

12.1 用 Tkinter 写最小界面

Python 自带 Tkinter,不需要额外库:

import tkinter as tk from tkinter import filedialog, messagebox import os from win32com.client import DispatchEx def select_folder(): folder = filedialog.askdirectory() entry_path.delete(0, tk.END) entry_path.insert(0, folder) def convert_now(): folder = entry_path.get() if not folder: messagebox.showwarning("提示", "请先选择文件夹") return word = DispatchEx("Word.Application") word.Visible = False os.makedirs(os.path.join(folder, "pdf输出"), exist_ok=True) try: for filename in os.listdir(folder): if filename.lower().endswith((".docx", ".doc")): input_path = os.path.join(folder, filename) output_name = os.path.splitext(filename)[0] + ".pdf" output_path = os.path.join(folder, "pdf输出", output_name) doc = word.Documents.Open(os.path.abspath(input_path)) doc.SaveAs(os.path.abspath(output_path), FileFormat=17) doc.Close() messagebox.showinfo("完成", "批量转换完成") finally: word.Quit() app = tk.Tk() app.title("Word批量转PDF工具") app.geometry("480x160") tk.Label(app, text="选择文件夹:").pack(pady=5) entry_path = tk.Entry(app, width=50) entry_path.pack(pady=5) btn_choose = tk.Button(app, text="选择文件夹", command=select_folder) btn_choose.pack(pady=5) btn_convert = tk.Button(app, text="开始批量转换", command=convert_now) btn_convert.pack(pady=10) app.mainloop()

12.2 打 exe

pip install pyinstaller pyinstaller -F -w word_to_pdf.py

生成的 exe 在dist目录中。注意:这种 exe 需要在装有 Word/WPS 的电脑上运行,因为 win32com 是调用本机 Office 组件的。如果要脱离 Office 处理 docx 的生成工作,不要使用 pywin32,改用纯 python-docx 实现,那样的 exe 可以独立运行。

13. 超实用改造:接入 API 提供文档处理服务

办公自动化到后期,都会把重复操作封装成 HTTP 接口,方便前端或其他系统调用。

13.1 创建 FastAPI 文档生成服务

先安装 FastAPI 和 uvicorn:

pip install fastapi uvicorn python-multipart

创建一个接口服务,接收 JSON 数据,生成 word 文档并返回下载:

from fastapi import FastAPI from fastapi.responses import FileResponse from pydantic import BaseModel from docx import Document import os import uuid app = FastAPI() class ReportData(BaseModel): username: str department: str week: str tasks: list[str] @app.post("/api/generate_word") def generate_word(data: ReportData): doc = Document() doc.add_heading("周报 — " + data.username, level=1) doc.add_paragraph("部门:" + data.department) doc.add_paragraph("周次:" + data.week) doc.add_heading("本周工作", level=2) for task in data.tasks: doc.add_paragraph(task, style="List Bullet") output_dir = "D:/word_auto/api_output" os.makedirs(output_dir, exist_ok=True) file_name = f"{uuid.uuid4().hex}.docx" file_path = os.path.join(output_dir, file_name) doc.save(file_path) return FileResponse( file_path, filename=f"{data.username}_周报.docx", media_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document" ) if __name__ == "__main__": import uvicorn uvicorn.run("main:app", host="127.0.0.1", port=8000)

13.2 调用接口示例

启动服务后,用 curl 或 requests 调用:

curl -X POST "http://127.0.0.1:8000/api/generate_word" ^ -H "Content-Type: application/json" ^ -d "{\"username\":\"王五\",\"department\":\"技术部\",\"week\":\"第3周\",\"tasks\":[\"任务A\",\"任务B\"]}" ^ -o test_report.docx

Python 调用:

import requests url = "http://127.0.0.1:8000/api/generate_word" payload = { "username": "王五", "department": "技术部", "week": "第3周", "tasks": ["完成API开发", "编写测试文档"] } resp = requests.post(url, json=payload) with open("output.docx", "wb") as f: f.write(resp.content)

服务一旦跑通,就可以嵌入到 OA 系统里,让前端按钮直接触发 word 文档生成下载,不需要人工复制粘贴。

13.3 接口服务的边界说明

接口服务一旦开启,允许别人通过 POST 请求生成文档,必须考虑:

  • 部署在内网或绑定 127.0.0.1,避免外部用户无限制调用;
  • 为接口增加认证鉴权;
  • 设置上传大小限制;
  • 如果生成文档内容包含用户隐私数据,输出文件需要设为临时文件,定时清理。

14. 常见操作细节与坑位清单

这一节把实战中容易出问题的点集中列出,帮助少走弯路。

14.1 中文字体设置

默认生成的 docx 使用 Word 的默认字体。在中文 Windows 上通常是等线或宋体,但如果需要在 Linux 服务器上生成,系统没有对应中文字体会导致 Word 打开时字体替换。更稳妥的方法是直接指定中文字体:

from docx import Document from docx.shared import Pt from docx.oxml.ns import qn doc = Document() style = doc.styles["Normal"] style.font.name = "微软雅黑" style._element.rPr.rFonts.set(qn("w:eastAsia"), "微软雅黑") style.font.size = Pt(11) doc.add_paragraph("中文字体测试") doc.save("D:/word_auto/output/font_test.docx")

必须同时设置w:eastAsia字体属性,否则中文字体名称不会生效。

14.2 段落对齐

python-docx 设置居中:

from docx.enum.text import WD_ALIGN_PARAGRAPH p = doc.add_paragraph() p.alignment = WD_ALIGN_PARAGRAPH.CENTER

14.3 插入分页符

from docx.enum.text import WD_BREAK p = doc.add_paragraph() run = p.add_run() run.add_break(WD_BREAK.PAGE)

14.4 获取 docx 文件里的所有文本

调试阶段经常要打印文档内容。用 python-docx 遍历段落表格:

from docx import Document doc = Document("D:/word_auto/input/test.docx") for p in doc.paragraphs: print(p.text) for table in doc.tables: for row in table.rows: for cell in row.cells: print(cell.text)

如果不输出任何结果,可能是表格内容嵌在文本框或 SmartArt 中,需要在 Word 里手动检查。

15. 最佳实践与工程化建议

15.1 文档模板与代码分离

批量生成 word 文档时,不要把样式写死在大量 Python 代码中。更好的做法是准备一个.docx模板,在里面写好“占位符”,用 Python 扫描并替换占位符。

例如模板里写{姓名}{部门},代码里做替换:

def fill_template(template_path, output_path, values: dict): from docx import Document doc = Document(template_path) for paragraph in doc.paragraphs: for key, value in values.items(): placeholder = "{" + key + "}" if placeholder in paragraph.text: # 工作区逐 run 替换 pass for table in doc.tables: for row in table.rows: for cell in row.cells: for key, value in values.items(): placeholder = "{" + key + "}" for p in cell.paragraphs: if placeholder in p.text: p.text = p.text.replace(placeholder, str(value)) doc.save(output_path)

模板化最大的好处是:同事或业务方可以直接改 docx 里的样式,不需要重新交付 Python 代码。

15.2 批量任务要留日志

批量处理几十上百个文件时,脚本崩溃后要知道卡在哪个文件。加日志的第一选择是标准库 logging,而不是到处都是 print。

import logging logging.basicConfig( filename="D:/word_auto/logs/batch.log", level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s", encoding="utf-8" ) logging.info("开始处理: report_001.docx") logging.error("处理失败: report_003.docx")

15.3 先用小样本试跑

不要一开始就跑全量。复制两三个文件到 sample 目录,先验证脚本逻辑,确认输出打开后排版正确,再执行整目录批量处理。

15.4 目录结构固定

建议在任何项目中都保持固定目录:

project/ ├─ data/input/ # 原始文件 ├─ data/output/ # 输出文件 ├─ data/backup/ # 备份原始文件 ├─ scripts/ # Python脚本 └─ logs/ # 日志

脚本使用pathlib而不是手写字符串拼接路径,避免路径分隔符在不同操作系统上的差异:

from pathlib import Path input_dir = Path("D:/word_auto/input") output_dir = Path("D:/word_auto/output") output_dir.mkdir(parents=True, exist_ok=True)

15.5 涉及第三方文档的合规要求

如果你是处理公司内部资料、客户合同、他人简历、或者任何含个人信息的文档,必须确认处理行为在授权范围内;测试数据要用自己生成的假数据,不要用真实身份证号、手机号跑测试脚本。

16. 思考:从单脚本到办公室自动化平台

回到项目标题python办公自动化word-doc。当前课程水平对应的不仅是“会用某个库”,而是建立一套处理文档的流程:

  1. 明确任务类型:生成新文档、修改已有文档、批量格式转换、内容抽取;
  2. 选择工具链:python-docx 用于纯代码读写,win32com 用于和 Word 应用交互,pdf2docx 用于 PDF 反向转出;
  3. 封装成函数:每个功能做成独立函数,输入路径输出路径都用参数化;
  4. 测试与备份:先小样本测试,任何批量修改之前备份一份原始目录;
  5. 自动化调度:如果每周都要执行一次,可以把脚本挂到 Windows 任务计划程序里定时运行。

如果这套脚本被多个同事使用,下一步自然是做成 web 服务或 exe 小工具。这也就是很多 python 办公自动化训练营最终要完成的目标。

文档处理类任务的难点不是某个 API 记不住,而是格式细节太多了。先跑通逻辑,再迭代排版细节,会顺利很多。

后面的学习中,可以继续看 python-docx 官方文档、python-pptx 用于 PPT 自动化、openpyxl 用于 Excel 自动化。热词里“python办公自动化excel篇”“pdf转word”“python量化交易策略代码”这些方向,本质上都是同一个套路:读取结构化数据、填充模板、批量输出、转换格式。

如果时间有限,优先把本节中的replace_in_runs、表格填充、模板化三个函数存入自己的工具库,它们的使用频率会非常高。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/4 4:38:43

aigcbiye|AI5.0学术智能平台,一站式搞定论文全流程写作难题

官网 www.aigcbiye.com ,微信公众号 搜一搜 AIGCbiye 学术写作是学子与科研人员的必经之路,从开题构思、文献梳理到正文撰写、数据论证,再到查重降重、答辩筹备,完整的论文创作流程繁琐复杂、专业性极强。多数创作者常陷入思路…

作者头像 李华
网站建设 2026/9/4 4:36:57

星盘接口开发文档:计算时区夏令时接口指南

星盘接口开发文档:计算时区夏令时接口指南 1. 引言 本文档详细介绍了占星系统的计算时区夏令时接口的使用方法,包括请求参数详解、响应数据结构、错误处理机制以及最佳实践建议。 2. 接口基础信息 接口名称: 计算时区夏令时 请求方式: POSTContent-Type:…

作者头像 李华
网站建设 2026/9/4 4:36:11

基于SpringBoot+Vue的智慧农业物联网平台全栈开发实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/4 4:35:59

沉浸式洗摩托车全流程:从精洗工位到预约工单管理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/4 4:35:25

基于Python与Playwright的京东库存监控与自动下单桌面应用开发实践

简介:这是一套面向个人学习者的京东商品库存监控与自动下单系统源码,适用于希望掌握电商自动化脚本开发、跨平台GUI应用实践及微信消息集成的Python初学者与进阶开发者。系统提供命令行(Shell)与图形界面(GUI&#xff…

作者头像 李华