1. 什么是 python-docx? #
- python-docx 是 Python 中最常用的 Word 文档处理库(当前主流版本 1.2.x),专门读写
.docx 格式。
- 通过 Python 代码创建、读取、修改 Word,无需安装 Microsoft Word。
- 典型场景:批量生成合同/周报/证书、从 Word 提取文字、按模板填充数据。
- 只支持
.docx(Word 2007+),不支持旧版 .doc 格式。
- 核心公式:Document 对象 + add_xxx 方法 + save()。
2. 核心概念 #
| 对象 |
含义 |
常用操作 |
| Document |
整个 Word 文件 |
Document()、save() |
| Paragraph |
一段文字 |
add_paragraph()、paragraph.text |
| Run |
段落内的一段文字(可单独设样式) |
add_run()、run.bold = True |
| Table |
表格 |
add_table()、table.cell(row, col).text |
- 一个段落可包含多个 Run,例如「普通加粗普通」= 三个 Run。
- 表格单元格索引从 0 开始:
table.cell(0, 0) 是第一行第一列。
.docx 本质是 ZIP 压缩包,python-docx 在内部读写其中的 XML。
3. 环境准备 #
- 安装
python-docx 即可使用,包名带连字符,导入时用 docx。
- 推荐 Python 3.9 及以上版本(1.2.x 支持 Python 3.8+)。
3.1 安装 #
py -m pip install --upgrade pip
py -m pip install python-docx
- 下载慢时可加镜像:
py -m pip install python-docx -i https://pypi.tuna.tsinghua.edu.cn/simple
3.2 验证安装 #
- 运行下面脚本,能生成
test.docx 即表示环境正常。
from docx import Document
doc = Document()
doc.add_paragraph("python-docx 安装成功")
doc.save("test.docx")
print("已创建 test.docx")
4. 创建与读取文档 #
Document() 创建空白文档;Document("文件.docx") 打开已有文档。
add_heading(text, level=1) 添加标题(level 1–9)。
add_paragraph(text) 添加段落。
doc.paragraphs 获取所有段落,.text 读取段落文字。
- 完成后调用
doc.save(path) 保存。
from docx import Document
doc = Document()
doc.add_heading("python-docx 入门", level=1)
doc.add_heading("第一章", level=2)
doc.add_paragraph("这是第一段。")
doc.add_paragraph("这是第二段。")
doc.save("example.docx")
doc2 = Document("example.docx")
for p in doc2.paragraphs:
print(p.text)
print(f"共 {len(doc2.paragraphs)} 个段落")
5. 文本格式与列表 #
- 段落级样式用
paragraph.alignment 等;字符级样式用 Run 设置。
- 粗体、斜体、字号、颜色都作用在 Run 上。
- 无序列表用
style="List Bullet",有序列表用 style="List Number"。
- 中文项目需同时设置西文字体名和东亚字体(见 §9.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)
para = doc.add_paragraph()
para.add_run("普通 ")
bold = para.add_run("加粗")
bold.bold = True
red = para.add_run(" 红色")
red.font.size = Pt(14)
red.font.color.rgb = RGBColor(255, 0, 0)
center = doc.add_paragraph("居中段落")
center.alignment = WD_ALIGN_PARAGRAPH.CENTER
for item in ["需求分析", "方案设计", "测试上线"]:
doc.add_paragraph(item, style="List Bullet")
for step in ["准备环境", "编写脚本", "生成文档"]:
doc.add_paragraph(step, style="List Number")
doc.save("format_list.docx")
print("已保存 format_list.docx")
6. 表格操作 #
add_table(rows, cols) 创建指定行列数的表格。
table.cell(row, col).text = "值" 写入单元格(行列均从 0 开始)。
table.style = "Table Grid" 设置带边框的网格样式。
- 读取已有文档中的表格:遍历
doc.tables,再访问 .cell()。
from docx import Document
doc = Document()
doc.add_heading("员工信息表", level=1)
table = doc.add_table(rows=4, cols=4)
table.style = "Table Grid"
headers = ["姓名", "岗位", "部门", "城市"]
for i, h in enumerate(headers):
table.cell(0, i).text = h
rows = [
["王芳", "工程师", "研发", "北京"],
["李伟", "产品经理", "产品", "上海"],
["张敏", "设计师", "设计", "广州"],
]
for ri, row in enumerate(rows, start=1):
for ci, val in enumerate(row):
table.cell(ri, ci).text = val
doc.save("table.docx")
print("已保存 table.docx")
7. 插入图片 #
- 在 Run 上调用
add_picture(路径, width=...) 插入图片。
- 只支持本地文件路径或二进制流,不支持 URL,网络图片需先下载。
- 用
Inches() 或 Cm() 控制宽度,高度会按比例缩放。
import os
from docx import Document
from docx.shared import Inches
from docx.enum.text import WD_ALIGN_PARAGRAPH
doc = Document()
doc.add_heading("图片示例", level=1)
image_path = "logo.png"
if os.path.exists(image_path):
para = doc.add_paragraph()
run = para.add_run()
run.add_picture(image_path, width=Inches(2.5))
para.alignment = WD_ALIGN_PARAGRAPH.CENTER
else:
doc.add_paragraph(f"请将图片放到当前目录:{image_path}")
doc.save("image.docx")
print("已保存 image.docx")
8. 实战:批量生成文档 #
- 实际项目中最常见的模式:模板 + 数据循环 + save。
- 简单占位符替换:遍历
doc.paragraphs,用 str.replace() 替换 {{KEY}}。
- 表格、页眉中的占位符需单独遍历
doc.tables 等,本示例仅演示段落。
from docx import Document
from datetime import datetime
def fill_contract(template_path: str, output_path: str, client: dict) -> None:
"""读取模板、替换占位符并保存。"""
doc = Document(template_path)
for para in doc.paragraphs:
para.text = para.text.replace("{{CLIENT}}", client["name"])
para.text = para.text.replace("{{AMOUNT}}", str(client["amount"]))
para.text = para.text.replace(
"{{DATE}}", datetime.now().strftime("%Y年%m月%d日")
)
doc.save(output_path)
if __name__ == "__main__":
tpl = Document()
tpl.add_heading("服务合同", level=1)
tpl.add_paragraph("甲方:{{CLIENT}}")
tpl.add_paragraph("合同金额:{{AMOUNT}} 元")
tpl.add_paragraph("签订日期:{{DATE}}")
tpl.save("contract_template.docx")
clients = [
{"name": "北京科技有限公司", "amount": 50000},
{"name": "上海贸易有限公司", "amount": 75000},
]
for c in clients:
out = f"合同_{c['name']}.docx"
fill_contract("contract_template.docx", out, c)
print("已生成:", out)
9. 常见问题 #
9.1 中文字体不生效 #
- Word 中西文字体与东亚字体分开设置,只设
font.name 往往不够。
- 需额外设置
w:eastAsia 字体(Windows 常用「微软雅黑」)。
from docx import Document
from docx.oxml.ns import qn
doc = Document()
para = doc.add_paragraph("中文字体测试")
for run in para.runs:
run.font.name = "微软雅黑"
run._element.rPr.rFonts.set(qn("w:eastAsia"), "微软雅黑")
doc.save("chinese_font.docx")
9.2 文件打不开或损坏 #
- 保存前确保目标文件未被 Word 或其他程序占用。
- 用
try/except 包裹 save(),避免异常中断导致半成品文件。
9.3 其他注意点 #
- 不支持
.doc 旧格式,需先用 Word 另存为 .docx。
- 修改
paragraph.text 会清除该段落内所有 Run 样式,替换占位符时注意。
- 页眉页脚、合并单元格、页面横竖向等高级排版 python-docx 支持有限,复杂排版建议保留 Word 模板。
10. API 速查 #
- 下面汇总 python-docx 1.2.x 日常最常用的写法。
| 操作 |
写法 |
| 创建文档 |
doc = Document() |
| 打开文档 |
doc = Document("a.docx") |
| 添加标题 |
doc.add_heading("标题", level=1) |
| 添加段落 |
doc.add_paragraph("文字") |
| 添加 Run |
run = para.add_run("文字"); run.bold = True |
| 无序列表 |
doc.add_paragraph("项", style="List Bullet") |
| 有序列表 |
doc.add_paragraph("项", style="List Number") |
| 创建表格 |
table = doc.add_table(rows=3, cols=4) |
| 写单元格 |
table.cell(0, 0).text = "值" |
| 插入图片 |
run.add_picture("a.png", width=Inches(2)) |
| 读取段落 |
for p in doc.paragraphs: p.text |
| 读取表格 |
for t in doc.tables: t.cell(r, c).text |
| 保存 |
doc.save("out.docx") |
| 居中 |
para.alignment = WD_ALIGN_PARAGRAPH.CENTER |
| 字号/颜色 |
run.font.size = Pt(14)、run.font.color.rgb = RGBColor(255,0,0) |