1. 什么是 python-docx? #
python-docx 是 Python 中最流行的 Word 文档处理库之一,专门用于读写 Microsoft Word 2007 及更高版本的文件格式(.docx)。它可以创建、读取、修改 Word 文档,支持段落、列表、表格、图片、页眉页脚等功能。
为什么要用 python-docx?
想象一下,你需要批量生成合同、周报、证书等 Word 文档,或者从 Word 中提取数据。手动操作太慢且容易出错,而 python-docx 提供了强大的 Python API,可以自动化完成这些任务。
python-docx 的优势:
- 功能强大:支持段落、列表、表格、图片、页眉页脚等所有常见操作
- 纯 Python 实现:不需要安装 Microsoft Word
- 跨平台:Windows、macOS、Linux 都可以使用
- 易于学习:API 设计简洁直观,文档完善
- 兼容性好:支持 Word 2007 及以上版本
前置知识补充:
- Word 文档结构:Word 文档(.docx)由文档(Document)组成,文档包含节(Section),每个节包含段落(Paragraph)、表格(Table)、图片(Picture)等元素。段落是 Word 中的基本文本单位。
- 段落(Paragraph):段落是 Word 文档中的一段文本,类似于文章中的一个段落。每个段落可以包含多个文本片段(Run)。
- Run(文本片段):Run 是段落中的一个文本片段,可以有独立的样式(如粗体、斜体、颜色等)。一个段落可以包含多个 Run。
- 表格(Table):表格由行(Row)和列(Column)组成,行和列的交集是单元格(Cell)。
- DOCX 格式:DOCX 是开放 XML 格式,本质上是一个 ZIP 压缩包,包含多个 XML 文件。python-docx 处理这些 XML 文件来创建和修改文档。
2. 环境准备 #
在学习 python-docx 之前,需要确保你的 Python 环境已经准备好。python-docx 支持 Python 3.6 及以上版本。
2.1 检查 Python 版本 #
在安装之前,先检查一下你的 Python 版本是否符合要求。
# Windows PowerShell:查看 Python 版本
python --version# macOS 终端:查看 Python 版本
python3 --version2.2 安装 python-docx #
python-docx 可以直接通过 pip 安装。安装过程会自动下载所需的依赖包。
# 说明:Windows PowerShell 安装 python-docx
# 先升级 pip 到最新版本,确保能正常安装依赖
python -m pip install --upgrade pip
# 安装 python-docx 库
python -m pip install python-docx# 说明:macOS / Linux 终端安装 python-docx
# 先升级 pip 到最新版本
python3 -m pip install --upgrade pip
# 安装 python-docx 库
python3 -m pip install python-docx网络加速提示:如果从 PyPI 下载较慢,可以使用国内镜像:
- Windows:
python -m pip install python-docx -i https://pypi.tuna.tsinghua.edu.cn/simple- macOS:
python3 -m pip install python-docx -i https://pypi.tuna.tsinghua.edu.cn/simple
安装问题提示:
- 如果安装失败,可能是因为网络问题。可以尝试使用镜像源,或者检查网络连接。
- macOS 用户如果遇到权限问题,可以在命令前加
sudo(不推荐),或者使用虚拟环境。- DOCX 文件是开放 XML 格式,安装后即可离线使用,无需安装 Microsoft Office。
2.3 验证安装 #
安装完成后,验证一下是否安装成功。
# -*- coding: utf-8 -*-
# 说明:验证 python-docx 是否安装成功
# 说明:导入 docx 模块
# python-docx 库的导入名是 docx
import docx
# 说明:打印 python-docx 版本信息(如果可用)
# 注意:python-docx 可能没有 __version__ 属性
try:
print(f"python-docx 版本:{docx.__version__}")
except AttributeError:
print("python-docx 已安装(版本信息不可用)")
# 说明:测试创建一个空的 Word 文档
# Document() 创建一个新的空文档对象
doc = docx.Document()
# 说明:添加一个测试段落
# add_paragraph() 方法在文档末尾添加一个新段落
doc.add_paragraph("测试文本")
# 说明:保存文档到文件
# save() 方法将文档保存到指定的文件路径
doc.save("test.docx")
# 说明:打印结果,验证安装是否成功
print("安装成功!已创建测试文件:test.docx")
# 说明:如果没有报错并创建了 test.docx 文件,说明安装成功3. 核心概念 #
在使用 python-docx 之前,需要理解几个核心概念。这些概念是理解 python-docx 的基础。
3.1 Document(文档对象) #
Document 是 Word 文档的对象表示,相当于整个 Word 文件。你可以通过 Document() 创建新的文档,或通过 Document(filename) 加载已有的文档。
3.2 Paragraph(段落对象) #
Paragraph 是文档中的一个段落,类似于文章中的一个段落。每个段落可以包含文本内容,也可以包含多个 Run(文本片段)。
3.3 Run(文本片段对象) #
Run 是段落中的一个文本片段,可以有独立的样式(如粗体、斜体、颜色等)。一个段落可以包含多个 Run,每个 Run 可以有不同的样式。
3.4 Table(表格对象) #
Table 是文档中的一个表格,由行(Row)和列(Column)组成。每个表格包含多个单元格(Cell),可以设置表格样式和列宽。
4. 快速体验:创建和读取文档 #
让我们通过一个最简单的例子来快速体验 python-docx 的强大功能。
4.1 创建 Word 文档 #
| 方法 | 功能说明 | 常用参数 | 返回值 |
|---|---|---|---|
Document() |
创建一个新的空文档 | 无 | Document 对象 |
.add_paragraph() |
在文档末尾添加一个新段落 | text:段落文本(可选),style:段落样式(可选) |
Paragraph 对象 |
.save() |
保存文档到文件 | path:文件路径 |
无 |
# -*- coding: utf-8 -*-
# 说明:快速体验 python-docx - 创建 Word 文档
# 说明:导入 docx 模块
# 从 docx 导入 Document 类,用于创建和操作 Word 文档
from docx import Document
# 说明:创建一个新的空 Word 文档
# Document() 函数创建一个新的空文档对象
doc = Document()
# 说明:添加一个段落
# add_paragraph() 方法在文档末尾添加一个新段落
# 参数是段落文本(可选,也可以不传参数创建空段落)
doc.add_paragraph("你好,python-docx!")
# 说明:保存文档到文件
# save() 方法将文档保存到指定的文件路径
# 如果文件已存在,会被覆盖;如果不存在,会创建新文件
doc.save("hello.docx")
# 说明:打印成功消息
print("Word 文档已创建:hello.docx")4.2 读取 Word 文档 #
| 方法/属性 | 功能说明 | 常用参数 | 返回值 |
|---|---|---|---|
Document() |
加载已有的文档 | docx:文件路径 |
Document 对象 |
.paragraphs |
获取文档中的所有段落 | 无(属性) | 段落对象列表 |
.text |
获取段落的文本内容 | 无(属性) | 字符串 |
# -*- coding: utf-8 -*-
# 说明:快速体验 python-docx - 读取 Word 文档
# 说明:导入 docx 模块
from docx import Document
# 说明:打开已有的 Word 文档
# Document() 函数可以接受文件路径参数,加载已有的文档
# 返回 Document 对象
doc = Document("hello.docx")
# 说明:遍历文档中的所有段落
# paragraphs 属性返回文档中所有段落的列表
for paragraph in doc.paragraphs:
# 说明:text 属性获取段落的文本内容
# 返回一个字符串,包含段落的所有文本
print(paragraph.text)
# 说明:打印段落数量
print(f"\n文档共包含 {len(doc.paragraphs)} 个段落")5. 创建和读取文档:详细操作 #
本节详细介绍如何创建和读取 Word 文档,包括添加标题、段落等基本操作。
5.1 创建文档并添加内容 #
| 方法 | 功能说明 | 常用参数 | 返回值 |
|---|---|---|---|
Document() |
创建新文档 | 无 | Document 对象 |
.add_heading() |
添加标题 | text:标题文本,level:标题级别(1-9) |
Paragraph 对象 |
.add_paragraph() |
添加段落 | text:段落文本(可选) |
Paragraph 对象 |
.save() |
保存文档 | path:文件路径 |
无 |
# -*- coding: utf-8 -*-
# 说明:演示如何创建 Word 文档并添加标题和段落
# 说明:导入 docx 模块
from docx import Document
# 说明:创建一个新的空 Word 文档
doc = Document()
# 说明:添加一级标题
# add_heading() 方法添加标题
# 参数1:标题文本
# 参数2:标题级别(1 表示一级标题,2 表示二级标题,依此类推,最大到 9)
doc.add_heading("python-docx 入门", level=1)
# 说明:添加二级标题
# level=2 表示二级标题
doc.add_heading("第一章:基础知识", level=2)
# 说明:添加正文段落
# add_paragraph() 方法添加段落
# 参数是段落文本
doc.add_paragraph("这是第一个段落。")
# 说明:添加更多段落
doc.add_paragraph("这是第二个段落。")
doc.add_paragraph("这是第三个段落。")
# 说明:保存文档到文件
doc.save("example.docx")
# 说明:打印成功消息
print("Word 文档已创建:example.docx")
print(f"文档包含 {len(doc.paragraphs)} 个段落")5.2 读取文档内容 #
| 方法/属性 | 功能说明 | 常用参数 | 返回值 |
|---|---|---|---|
Document() |
加载已有文档 | docx:文件路径 |
Document 对象 |
.paragraphs |
获取所有段落 | 无(属性) | 段落对象列表 |
.text |
获取段落文本 | 无(属性) | 字符串 |
.style |
获取段落样式 | 无(属性) | 样式名称 |
# -*- coding: utf-8 -*-
# 说明:演示如何读取 Word 文档的内容
# 说明:导入 docx 模块
from docx import Document
# 说明:先创建一个示例文档用于演示
print("创建示例文档...")
doc_example = Document()
doc_example.add_heading("示例标题", level=1)
doc_example.add_paragraph("这是第一段内容。")
doc_example.add_paragraph("这是第二段内容。")
doc_example.save("example_read.docx")
print("示例文档已创建:example_read.docx\n")
# 说明:打开已有的 Word 文档
# Document() 函数接受文件路径作为参数,加载已有的文档
doc = Document("example_read.docx")
# 说明:遍历所有段落并打印内容
print("文档内容:")
for idx, paragraph in enumerate(doc.paragraphs, 1):
# 说明:text 属性获取段落的文本内容
text = paragraph.text
# 说明:style 属性获取段落的样式名称
style = paragraph.style.name
# 说明:打印段落信息和内容
print(f"\n段落 {idx}:")
print(f" 样式:{style}")
print(f" 内容:{text}")
# 说明:打印统计信息
print(f"\n文档统计:")
print(f" 总段落数:{len(doc.paragraphs)}")
# 说明:提取所有文本内容
all_text = "\n".join([p.text for p in doc.paragraphs])
print(f"\n完整文本内容:")
print(all_text)6. 段落和样式:文本格式化 #
python-docx 支持丰富的文本格式化功能,包括字体、颜色、对齐等。本节介绍如何设置段落和文本样式。
6.1 段落和 Run #
| 方法/属性 | 功能说明 | 常用参数 | 返回值 |
|---|---|---|---|
.add_paragraph() |
添加段落 | text:段落文本(可选) |
Paragraph 对象 |
.add_run() |
在段落中添加 Run(文本片段) | text:文本内容(可选) |
Run 对象 |
.bold |
设置或获取粗体 | 无(属性),可赋值为 True/False | 布尔值 |
.italic |
设置或获取斜体 | 无(属性),可赋值为 True/False | 布尔值 |
.font |
获取字体对象 | 无(属性) | Font 对象 |
.size |
设置或获取字体大小 | 无(属性),可赋值为 Pt 对象 | Pt 对象 |
.color.rgb |
设置或获取字体颜色 | 无(属性),可赋值为 RGBColor 对象 | RGBColor 对象 |
# -*- coding: utf-8 -*-
# 说明:演示如何设置段落和 Run 的样式
# 说明:导入 docx 模块和相关样式类
from docx import Document
from docx.shared import Pt, RGBColor
# 说明:创建新文档
doc = Document()
# 说明:添加一个段落
# add_paragraph() 方法添加段落,返回 Paragraph 对象
para = doc.add_paragraph("普通文字")
# 说明:在段落中添加 Run(文本片段)
# add_run() 方法在段落中添加一个文本片段
# 参数是文本内容(可选,也可以不传参数创建空 Run)
bold_run = para.add_run(" 加粗")
# 说明:设置 Run 为粗体
# bold 属性设置为 True 表示粗体,False 表示正常
bold_run.bold = True
# 说明:添加第二个 Run
italic_run = para.add_run(" 斜体")
# 说明:设置 Run 为斜体
# italic 属性设置为 True 表示斜体,False 表示正常
italic_run.italic = True
# 说明:添加第三个 Run(自定义样式)
custom_run = para.add_run(" 红色 14 号")
# 说明:设置 Run 的字体大小
# font.size 属性设置字体大小
# Pt(14) 表示 14 磅(point),Pt 是字体大小的单位
custom_run.font.size = Pt(14)
# 说明:设置 Run 的字体颜色
# font.color.rgb 属性设置字体颜色
# RGBColor(255, 0, 0) 表示红色(RGB 格式,值范围 0-255)
# 255 表示红色分量,0 表示绿色分量,0 表示蓝色分量
custom_run.font.color.rgb = RGBColor(255, 0, 0)
# 说明:保存文档
doc.save("text_styles.docx")
# 说明:打印成功消息
print("Word 文档已创建:text_styles.docx")
print("文档包含混合样式的段落(普通、粗体、斜体、红色)")6.2 段落对齐和间距 #
| 方法/属性 | 功能说明 | 常用参数 | 返回值 |
|---|---|---|---|
.alignment |
设置或获取段落对齐方式 | 无(属性),可赋值为对齐常量 | 对齐常量 |
.paragraph_format |
获取段落格式对象 | 无(属性) | ParagraphFormat 对象 |
.space_before |
设置段前间距 | 无(属性),可赋值为 Pt 对象 | Pt 对象 |
.space_after |
设置段后间距 | 无(属性),可赋值为 Pt 对象 | Pt 对象 |
# -*- coding: utf-8 -*-
# 说明:演示如何设置段落对齐和间距
# 说明:导入 docx 模块和对齐枚举
from docx import Document
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.shared import Pt
# 说明:创建新文档
doc = Document()
# 说明:添加左对齐段落(默认)
# add_paragraph() 方法添加段落
p_left = doc.add_paragraph("这是左对齐段落(默认)")
# 说明:alignment 属性设置段落对齐方式
# WD_ALIGN_PARAGRAPH.LEFT 表示左对齐(默认)
p_left.alignment = WD_ALIGN_PARAGRAPH.LEFT
# 说明:添加居中对齐段落
p_center = doc.add_paragraph("这是居中对齐段落")
# 说明:WD_ALIGN_PARAGRAPH.CENTER 表示居中对齐
p_center.alignment = WD_ALIGN_PARAGRAPH.CENTER
# 说明:添加右对齐段落
p_right = doc.add_paragraph("这是右对齐段落")
# 说明:WD_ALIGN_PARAGRAPH.RIGHT 表示右对齐
p_right.alignment = WD_ALIGN_PARAGRAPH.RIGHT
# 说明:添加两端对齐段落(需要足够长的文本)
# 重复文本以创建足够长的段落
p_justify = doc.add_paragraph("这是两端对齐段落示例。" * 10)
# 说明:WD_ALIGN_PARAGRAPH.JUSTIFY 表示两端对齐
p_justify.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
# 说明:设置段落间距
# paragraph_format 属性获取段落格式对象
# space_before 属性设置段前间距(段落之前的空白)
# Pt(12) 表示 12 磅的间距
p_justify.paragraph_format.space_before = Pt(12)
# 说明:space_after 属性设置段后间距(段落之后的空白)
p_justify.paragraph_format.space_after = Pt(12)
# 说明:保存文档
doc.save("alignment.docx")
# 说明:打印成功消息
print("Word 文档已创建:alignment.docx")
print("文档包含不同对齐方式的段落")7. 标题和列表:组织文档结构 #
Word 文档通常使用标题和列表来组织内容。本节介绍如何添加标题和列表。
7.1 添加标题 #
| 方法 | 功能说明 | 常用参数 | 返回值 |
|---|---|---|---|
.add_heading() |
添加标题 | text:标题文本,level:标题级别(1-9) |
Paragraph 对象 |
# -*- coding: utf-8 -*-
# 说明:演示如何添加多级标题
# 说明:导入 docx 模块
from docx import Document
# 说明:创建新文档
doc = Document()
# 说明:添加一级标题
# add_heading() 方法添加标题
# 参数1:标题文本
# 参数2:标题级别(1 表示一级标题,最大到 9)
doc.add_heading("一级标题", level=1)
# 说明:添加二级标题
# level=2 表示二级标题
doc.add_heading("二级标题", level=2)
# 说明:添加三级标题
# level=3 表示三级标题
doc.add_heading("三级标题", level=3)
# 说明:添加正文段落
doc.add_paragraph("这是正文内容。")
# 说明:添加四级标题
doc.add_heading("四级标题", level=4)
# 说明:添加更多段落
doc.add_paragraph("更多正文内容。")
# 说明:保存文档
doc.save("heading.docx")
# 说明:打印成功消息
print("Word 文档已创建:heading.docx")
print("文档包含多级标题和段落")7.2 添加列表 #
| 方法 | 功能说明 | 常用参数 | 返回值 |
|---|---|---|---|
.add_paragraph() |
添加段落,可以指定样式 | text:段落文本,style:段落样式 |
Paragraph 对象 |
# -*- coding: utf-8 -*-
# 说明:演示如何添加列表(项目符号和编号列表)
# 说明:导入 docx 模块
from docx import Document
# 说明:创建新文档
doc = Document()
# 说明:添加标题
doc.add_heading("项目列表示例", level=1)
# 说明:添加项目符号列表(无序列表)
# add_paragraph() 方法的 style 参数可以指定段落样式
# style="List Bullet" 表示项目符号列表样式
items = ["需求分析", "方案设计", "测试上线"]
for item in items:
# 说明:使用 style="List Bullet" 创建项目符号列表
doc.add_paragraph(item, style="List Bullet")
# 说明:添加空段落(用于分隔)
doc.add_paragraph()
# 说明:添加编号列表(有序列表)
# style="List Number" 表示编号列表样式
steps = ["准备环境", "编写脚本", "生成文档"]
for step in steps:
# 说明:使用 style="List Number" 创建编号列表
doc.add_paragraph(step, style="List Number")
# 说明:保存文档
doc.save("heading_list.docx")
# 说明:打印成功消息
print("Word 文档已创建:heading_list.docx")
print("文档包含标题、项目符号列表和编号列表")8. 表格操作:创建和填充表格 #
表格是 Word 文档中常用的元素。本节介绍如何创建表格、填充数据和设置样式。
8.1 创建表格并填充数据 #
| 方法/属性 | 功能说明 | 常用参数 | 返回值 |
|---|---|---|---|
.add_table() |
添加表格 | rows:行数,cols:列数 |
Table 对象 |
.style |
设置表格样式 | 无(属性),可赋值为样式名称 | 无 |
.cell() |
访问单元格 | row_idx:行索引(从 0 开始),col_idx:列索引(从 0 开始) |
Cell 对象 |
.text |
设置或获取单元格文本 | 无(属性),可赋值为字符串 | 字符串 |
# -*- coding: utf-8 -*-
# 说明:演示如何创建表格并填充数据
# 说明:导入 docx 模块
from docx import Document
# 说明:创建新文档
doc = Document()
# 说明:添加标题
doc.add_heading("员工信息表", level=1)
# 说明:创建表格
# add_table() 方法添加表格
# 参数1:rows=4 表示创建 4 行
# 参数2:cols=4 表示创建 4 列
# 返回 Table 对象
table = doc.add_table(rows=4, cols=4)
# 说明:设置表格样式
# style 属性设置表格样式
# "Table Grid" 表示带网格线的表格样式
table.style = "Table Grid"
# 说明:设置表头(第一行)
# 定义表头内容
headers = ["姓名", "岗位", "部门", "城市"]
# 说明:遍历表头,填充到第一行
# enumerate() 函数同时获取索引和值
for idx, text in enumerate(headers):
# 说明:table.cell(0, idx) 访问第一行第 idx 列的单元格(索引从 0 开始)
# text 属性设置单元格的文本内容
table.cell(0, idx).text = text
# 说明:准备表格数据
# 每一行是一个列表,包含该行的所有列数据
rows = [
["王芳", "工程师", "研发", "北京"],
["李伟", "产品经理", "产品", "上海"],
["张敏", "设计师", "设计", "广州"],
]
# 说明:填充数据行
# enumerate(rows, start=1) 从第二行开始(start=1 表示从索引 1 开始)
for row_idx, row in enumerate(rows, start=1):
# 说明:遍历当前行的所有列
for col_idx, value in enumerate(row):
# 说明:table.cell(row_idx, col_idx) 访问指定位置的单元格
# 设置单元格的文本内容
table.cell(row_idx, col_idx).text = value
# 说明:保存文档
doc.save("table_basic.docx")
# 说明:打印成功消息
print("Word 文档已创建:table_basic.docx")
print("文档包含一个 4x4 的表格(1 行表头 + 3 行数据)")8.2 设置列宽和合并单元格 #
| 方法/属性 | 功能说明 | 常用参数 | 返回值 |
|---|---|---|---|
.autofit |
设置是否自动调整列宽 | 无(属性),可赋值为 True/False | 布尔值 |
.columns |
获取所有列 | 无(属性) | Column 对象列表 |
.width |
设置列宽 | 无(属性),可赋值为 Inches 对象 | Inches 对象 |
.merge() |
合并单元格 | other_cell:要合并的另一个单元格 |
Cell 对象 |
# -*- coding: utf-8 -*-
# 说明:演示如何设置列宽和合并单元格
# 说明:导入 docx 模块和单位转换类
from docx import Document
from docx.shared import Inches
# 说明:创建新文档
doc = Document()
# 说明:添加标题
doc.add_heading("表格样式示例", level=1)
# 说明:创建表格
# 创建 2 行 3 列的表格
table = doc.add_table(rows=2, cols=3)
# 说明:禁用自动调整列宽
# autofit 属性设置为 False 表示不自动调整列宽
# 这样可以使用自定义的列宽
table.autofit = False
# 说明:设置列宽
# columns 属性返回所有列的列表
# columns[0] 表示第一列,columns[1] 表示第二列,依此类推
# width 属性设置列宽
# Inches(1) 表示 1 英寸,Inches 是长度单位
table.columns[0].width = Inches(1) # 第一列宽度为 1 英寸
table.columns[1].width = Inches(1.5) # 第二列宽度为 1.5 英寸
table.columns[2].width = Inches(2) # 第三列宽度为 2 英寸
# 说明:合并第一行的单元格
# table.cell(0, 0) 访问第一行第一列的单元格
# table.cell(0, 2) 访问第一行第三列的单元格
# merge() 方法将两个单元格合并,返回合并后的单元格对象
merged = table.cell(0, 0).merge(table.cell(0, 2))
# 说明:在合并后的单元格中设置文本
# text 属性设置单元格的文本内容
merged.text = "合并区域"
# 说明:填充第二行的数据
table.cell(1, 0).text = "A"
table.cell(1, 1).text = "B"
table.cell(1, 2).text = "C"
# 说明:保存文档
doc.save("table_merge.docx")
# 说明:打印成功消息
print("Word 文档已创建:table_merge.docx")
print("文档包含一个带合并单元格和自定义列宽的表格")9. 图片插入:在文档中添加图片 #
python-docx 支持在文档中插入图片。本节介绍如何插入图片并设置图片大小和对齐方式。
9.1 插入图片 #
| 方法 | 功能说明 | 常用参数 | 返回值 |
|---|---|---|---|
.add_paragraph() |
添加段落 | 无 | Paragraph 对象 |
.add_run() |
在段落中添加 Run | 无 | Run 对象 |
.add_picture() |
在 Run 中插入图片 | image_path_or_stream:图片路径或流,width:宽度(可选),height:高度(可选) |
InlineShape 对象 |
.alignment |
设置段落对齐方式 | 无(属性),可赋值为对齐常量 | 对齐常量 |
# -*- coding: utf-8 -*-
# 说明:演示如何在文档中插入图片
# 说明:导入 docx 模块和相关类
from docx import Document
from docx.shared import Inches
from docx.enum.text import WD_ALIGN_PARAGRAPH
import os
# 说明:创建新文档
doc = Document()
# 说明:添加标题
doc.add_paragraph("图片示例")
# 说明:创建一个新段落用于插入图片
# add_paragraph() 方法添加一个空段落
paragraph = doc.add_paragraph()
# 说明:在段落中添加一个 Run
# add_run() 方法在段落中添加一个文本片段(Run)
run = paragraph.add_run()
# 说明:在 Run 中插入图片
# add_picture() 方法在 Run 中插入图片
# 参数1:图片文件路径(必须是本地文件路径)
# 参数2:width 设置图片宽度(可选)
# Inches(2.5) 表示宽度为 2.5 英寸
# 如果只设置 width,高度会按比例自动调整
run.add_picture("logo.png", width=Inches(2.5))
# 说明:设置段落居中对齐
# alignment 属性设置段落对齐方式
# WD_ALIGN_PARAGRAPH.CENTER 表示居中对齐
paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
# 说明:保存文档
doc.save("image_demo.docx")
# 说明:打印成功消息
print("Word 文档已创建:image_demo.docx")
print("文档包含一张居中对齐的图片")
# 说明:如果图片文件不存在,给出提示
if not os.path.exists("logo.png"):
print("\n提示:logo.png 文件不存在")
print("请将图片文件放在当前目录下,或修改代码中的图片路径")注意:上面的代码需要当前目录中存在
logo.png图片文件。如果图片文件不存在,代码会报错。在实际使用中,请替换为你自己的图片文件路径。
9.2 插入多张图片 #
| 方法 | 功能说明 | 常用参数 | 返回值 |
|---|---|---|---|
.add_picture() |
插入图片 | image_path_or_stream:图片路径,width:宽度(可选),height:高度(可选) |
InlineShape 对象 |
# -*- coding: utf-8 -*-
# 说明:演示如何插入多张图片
# 说明:导入 docx 模块和相关类
from docx import Document
from docx.shared import Inches
from docx.enum.text import WD_ALIGN_PARAGRAPH
import os
# 说明:创建新文档
doc = Document()
# 说明:添加标题
doc.add_heading("图片集合", level=1)
# 说明:准备图片文件列表
# 这是示例图片路径列表,实际使用时请替换为你的图片路径
image_files = ["image1.png", "image2.jpg", "image3.png"]
# 说明:遍历每张图片并插入
for idx, image_file in enumerate(image_files, 1):
# 说明:检查图片文件是否存在
if os.path.exists(image_file):
# 说明:添加图片说明(可选)
doc.add_paragraph(f"图片 {idx}:{image_file}", style="Heading 3")
# 说明:创建新段落用于插入图片
paragraph = doc.add_paragraph()
run = paragraph.add_run()
# 说明:插入图片
# width 设置图片宽度为 3 英寸
run.add_picture(image_file, width=Inches(3))
# 说明:设置段落居中对齐
paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
# 说明:添加空段落用于分隔
doc.add_paragraph()
else:
# 说明:如果文件不存在,添加提示文本
doc.add_paragraph(f"图片 {idx} 不存在:{image_file}")
# 说明:保存文档
doc.save("images_demo.docx")
# 说明:打印成功消息
print("Word 文档已创建:images_demo.docx")
print("\n提示:")
print(" - 如果图片路径是网络地址,需要先下载到本地")
print(" - python-docx 只接受本地文件路径或二进制流")
print(" - 图片格式支持:PNG、JPG、GIF、BMP 等常见格式")10. 页面设置:页眉页脚和页面布局 #
python-docx 支持设置页面布局,包括页边距、纸张大小、横竖向以及页眉页脚。本节介绍如何设置这些属性。
10.1 设置页面布局 #
| 方法/属性 | 功能说明 | 常用参数 | 返回值 |
|---|---|---|---|
.sections |
获取文档的所有节 | 无(属性) | Section 对象列表 |
.orientation |
设置页面方向 | 无(属性),可赋值为方向常量 | 方向常量 |
.page_width |
设置页面宽度 | 无(属性),可赋值为 Inches 对象 | Inches 对象 |
.page_height |
设置页面高度 | 无(属性),可赋值为 Inches 对象 | Inches 对象 |
.top_margin |
设置上边距 | 无(属性),可赋值为 Inches 对象 | Inches 对象 |
.bottom_margin |
设置下边距 | 无(属性),可赋值为 Inches 对象 | Inches 对象 |
.left_margin |
设置左边距 | 无(属性),可赋值为 Inches 对象 | Inches 对象 |
.right_margin |
设置右边距 | 无(属性),可赋值为 Inches 对象 | Inches 对象 |
# -*- coding: utf-8 -*-
# 说明:演示如何设置页面布局(页边距、纸张大小、横竖向)
# 说明:导入 docx 模块和相关类
from docx import Document
from docx.shared import Inches
from docx.enum.section import WD_ORIENTATION
# 说明:创建新文档
doc = Document()
# 说明:添加内容
doc.add_heading("页面布局示例", level=1)
doc.add_paragraph("这是正文内容。")
doc.add_paragraph("这是另一段正文内容。")
# 说明:获取文档的第一个节
# sections 属性返回文档中所有节的列表
# sections[0] 表示第一个节(文档通常只有一个节)
section = doc.sections[0]
# 说明:设置页面方向为横向
# orientation 属性设置页面方向
# WD_ORIENTATION.LANDSCAPE 表示横向(横向比纵向宽)
# WD_ORIENTATION.PORTRAIT 表示纵向(默认,纵向比横向高)
section.orientation = WD_ORIENTATION.LANDSCAPE
# 说明:设置页面尺寸
# page_width 属性设置页面宽度
# page_height 属性设置页面高度
# Inches(11) 表示 11 英寸
section.page_width = Inches(11)
section.page_height = Inches(8.5)
# 说明:设置页边距(四边都是 1 英寸)
# top_margin 属性设置上边距
# bottom_margin 属性设置下边距
# left_margin 属性设置左边距
# right_margin 属性设置右边距
section.top_margin = Inches(1)
section.bottom_margin = Inches(1)
section.left_margin = Inches(1)
section.right_margin = Inches(1)
# 说明:保存文档
doc.save("page_layout.docx")
# 说明:打印成功消息
print("Word 文档已创建:page_layout.docx")
print("文档设置为横向页面,页边距为 1 英寸")10.2 添加页眉页脚 #
| 方法/属性 | 功能说明 | 常用参数 | 返回值 |
|---|---|---|---|
.header |
获取节页眉 | 无(属性) | HeaderFooter 对象 |
.footer |
获取节页脚 | 无(属性) | HeaderFooter 对象 |
.paragraphs |
获取页眉/页脚中的段落 | 无(属性) | 段落对象列表 |
.text |
设置段落文本 | 无(属性),可赋值为字符串 | 字符串 |
.alignment |
设置段落对齐 | 无(属性),可赋值为对齐常量 | 对齐常量 |
# -*- coding: utf-8 -*-
# 说明:演示如何添加页眉和页脚
# 说明:导入 docx 模块和相关类
from docx import Document
from docx.shared import Inches
from docx.enum.text import WD_ALIGN_PARAGRAPH
# 说明:创建新文档
doc = Document()
# 说明:添加文档内容
doc.add_heading("页眉页脚示例", level=1)
for i in range(5):
doc.add_paragraph(f"这是第 {i+1} 段内容。" * 10)
# 说明:获取文档的第一个节
section = doc.sections[0]
# 说明:设置页边距
section.top_margin = Inches(1)
section.bottom_margin = Inches(1)
section.left_margin = Inches(1)
section.right_margin = Inches(1)
# 说明:添加页眉
# header 属性获取节的页眉对象
# paragraphs[0] 表示页眉中的第一个段落(页眉默认有一个空段落)
header = section.header.paragraphs[0]
# 说明:设置页眉文本
# text 属性设置段落的文本内容
header.text = "项目周报"
# 说明:设置页眉居中对齐
# alignment 属性设置段落对齐方式
# WD_ALIGN_PARAGRAPH.CENTER 表示居中对齐
header.alignment = WD_ALIGN_PARAGRAPH.CENTER
# 说明:添加页脚
# footer 属性获取节的页脚对象
# paragraphs[0] 表示页脚中的第一个段落(页脚默认有一个空段落)
footer = section.footer.paragraphs[0]
# 说明:设置页脚文本
footer.text = "机密文档"
# 说明:设置页脚右对齐
# WD_ALIGN_PARAGRAPH.RIGHT 表示右对齐
footer.alignment = WD_ALIGN_PARAGRAPH.RIGHT
# 说明:保存文档
doc.save("page_header_footer.docx")
# 说明:打印成功消息
print("Word 文档已创建:page_header_footer.docx")
print("文档包含页眉(居中)和页脚(右对齐)")11. 实战案例:批量生成文档 #
下面是一个完整的实战案例,综合运用前面学到的知识,创建一个批量生成文档的工具。
11.1 批量生成合同 #
本代码块中使用的 python-docx 方法总结:
| 方法 | 功能说明 |
|---|---|
Document() |
创建或加载文档 |
.paragraphs |
获取所有段落 |
.text |
获取或设置文本 |
.save() |
保存文档 |
# -*- coding: utf-8 -*-
# 说明:实战案例 - 批量生成合同
# 综合运用前面学到的所有知识,创建一个批量生成合同的工具
# 说明:导入所需的库
from docx import Document
from datetime import datetime
import os
def fill_contract(template_path: str, output_path: str, client: dict) -> None:
"""
读取模板并替换占位符,生成个性化合同
参数:
template_path (str): 模板文件路径
output_path (str): 输出文件路径
client (dict): 客户信息字典(包含 name 和 amount)
"""
# 说明:打开模板文档
# Document() 函数接受文件路径参数,加载已有的文档
doc = Document(template_path)
# 说明:遍历文档中的所有段落
# paragraphs 属性返回文档中所有段落的列表
for paragraph in doc.paragraphs:
# 说明:替换占位符 {{CLIENT}} 为客户名称
# text 属性获取段落的文本内容
# replace() 方法替换字符串中的文本
# {{CLIENT}} 是占位符,会被替换为实际的客户名称
paragraph.text = paragraph.text.replace("{{CLIENT}}", client["name"])
# 说明:替换占位符 {{AMOUNT}} 为金额
# str() 函数将数字转换为字符串
paragraph.text = paragraph.text.replace("{{AMOUNT}}", str(client["amount"]))
# 说明:替换占位符 {{DATE}} 为当前日期
# datetime.now() 获取当前日期和时间
# strftime() 方法格式化日期
# "%Y年%m月%d日" 是日期格式,例如:2024年01月15日
paragraph.text = paragraph.text.replace("{{DATE}}", datetime.now().strftime("%Y年%m月%d日"))
# 说明:保存生成的文件
# save() 方法将文档保存到指定的文件路径
doc.save(output_path)
# 说明:主程序入口
if __name__ == "__main__":
# 说明:先创建一个示例模板用于演示
print("创建示例模板...")
template_doc = Document()
template_doc.add_heading("服务合同", level=1)
template_doc.add_paragraph("甲方:{{CLIENT}}")
template_doc.add_paragraph("合同金额:{{AMOUNT}} 元")
template_doc.add_paragraph("签订日期:{{DATE}}")
template_doc.add_paragraph("本合同自签订之日起生效。")
template_doc.save("contract_template.docx")
print("示例模板已创建:contract_template.docx\n")
# 说明:准备客户列表
# 每个客户是一个字典,包含名称和金额
clients = [
{"name": "北京科技有限公司", "amount": 50000},
{"name": "上海贸易有限公司", "amount": 75000},
{"name": "广州实业有限公司", "amount": 30000},
]
# 说明:遍历每个客户,批量生成合同
print("批量生成合同:")
for client in clients:
# 说明:生成输出文件名
# 文件名包含客户名称
filename = f"合同_{client['name']}.docx"
# 说明:调用函数生成合同
fill_contract("contract_template.docx", filename, client)
print(f" 已生成:{filename}")
print("\n批量生成完成!")12. 常见问题与排查 #
在使用 python-docx 时,可能会遇到一些常见问题。本节提供解决方案。
12.1 中文字体显示问题 #
问题:设置的中文字体不生效,在 Word 中显示为默认字体。
原因:Word 对中文字体和英文字体有区分,需要同时设置两种字体。
解决方案:
| 方法/属性 | 功能说明 | 常用参数 | 返回值 |
|---|---|---|---|
.font.name |
设置字体名称 | 无(属性),可赋值为字体名称 | 字符串 |
._element.rPr.rFonts.set() |
设置东亚字体(用于中文) | qn:命名空间,字体名称 |
无 |
# -*- coding: utf-8 -*-
# 说明:演示如何正确设置中文字体
# 说明:导入 docx 模块和命名空间工具
from docx import Document
from docx.oxml.ns import qn
# 说明:创建新文档
doc = Document()
# 说明:添加一个包含中文的段落
para = doc.add_paragraph("中文字体测试")
# 说明:遍历段落中的所有 Run
# runs 属性返回段落中所有 Run 的列表
for run in para.runs:
# 说明:设置英文字体名称
# font.name 属性设置字体名称
# "微软雅黑" 是 Windows 系统的中文字体
run.font.name = "微软雅黑"
# 说明:设置东亚字体(用于中文)
# _element 访问底层的 XML 元素
# rPr 是运行属性(run properties)
# rFonts 是字体设置
# set() 方法设置字体
# qn("w:eastAsia") 创建命名空间限定名称,用于设置东亚字体
run._element.rPr.rFonts.set(qn("w:eastAsia"), "微软雅黑")
# 说明:保存文档
doc.save("chinese_font.docx")
# 说明:打印成功消息
print("Word 文档已创建:chinese_font.docx")
print("文档包含正确设置的中文字体")
# 说明:macOS 用户的字体设置示例
print("\n提示:")
print(" - Windows 用户可以使用:微软雅黑、宋体、黑体等")
print(" - macOS 用户可以使用:PingFang SC、STSong、STHeiti 等")
print(" - 确保字体名称与系统中的实际字体名称一致")12.2 文件损坏问题 #
问题:保存后的 Word 文件无法打开或提示损坏。
原因:通常是文件被其他程序占用,或者在写入过程中程序异常退出。
解决方案:
# -*- coding: utf-8 -*-
# 说明:演示如何避免文件损坏问题
# 说明:导入 docx 模块和 zipfile 模块(用于检测文件)
from docx import Document
import zipfile
import os
# 说明:方法1:使用 try-except 确保文件正确保存
try:
# 说明:创建新文档
doc = Document()
doc.add_paragraph("测试内容")
# 说明:保存文件
doc.save("safe_save.docx")
print("文件已保存:safe_save.docx")
except Exception as e:
# 说明:如果保存失败,捕获异常
print(f"保存失败:{e}")
# 说明:方法2:检测 DOCX 文件是否损坏
def is_valid_docx(path: str) -> bool:
"""
检测 DOCX 文件是否损坏(通过检查 ZIP 结构)
参数:
path (str): 文件路径
返回:
bool: 如果文件有效返回 True,否则返回 False
"""
# 说明:检查文件是否存在
if not os.path.exists(path):
return False
try:
# 说明:DOCX 文件本质上是一个 ZIP 压缩包
# 使用 zipfile 尝试打开文件,如果能正常打开说明文件格式正确
with zipfile.ZipFile(path) as archive:
return True
except zipfile.BadZipFile:
# 说明:如果 ZIP 结构损坏,返回 False
return False
except Exception as e:
# 说明:其他异常也返回 False
print(f"检测文件时出错:{e}")
return False
# 说明:使用示例
filepath = "safe_save.docx"
if is_valid_docx(filepath):
print(f"文件 {filepath} 有效")
else:
print(f"文件 {filepath} 可能损坏或不存在")12.3 图片路径问题 #
问题:插入图片时提示文件不存在。
解决方案:
# -*- coding: utf-8 -*-
# 说明:演示如何处理图片路径问题
# 说明:导入 docx 模块和 os 模块
from docx import Document
from docx.shared import Inches
import os
# 说明:创建新文档
doc = Document()
# 说明:图片文件路径
image_path = "logo.png"
# 说明:方法1:先检查文件是否存在
if os.path.exists(image_path):
# 说明:文件存在,可以安全插入
paragraph = doc.add_paragraph()
run = paragraph.add_run()
run.add_picture(image_path, width=Inches(2.5))
print(f"图片已插入:{image_path}")
else:
# 说明:文件不存在,添加提示文本
doc.add_paragraph(f"图片文件不存在:{image_path}")
print(f"错误:图片文件不存在:{image_path}")
# 说明:保存文档
doc.save("image_check.docx")
# 说明:提示信息
print("\n提示:")
print(" - python-docx 只接受本地文件路径,不支持网络地址")
print(" - 如果图片在网络上,需要先使用 requests 等库下载到本地")
print(" - 支持常见图片格式:PNG、JPG、GIF、BMP 等")12.4 性能优化建议 #
问题:批量生成大量文档时速度慢。
解决方案:
# -*- coding: utf-8 -*-
# 说明:演示性能优化技巧
# 说明:导入 docx 模块和 time 模块(用于计时)
from docx import Document
from docx.shared import Pt, RGBColor
import time
print("性能优化建议:")
print("\n1. 复用样式对象(避免在循环中重复创建):")
# 说明:方法1:在循环外创建样式对象(推荐)
doc1 = Document()
# 说明:在循环外创建样式对象
font_size = Pt(12)
font_color = RGBColor(255, 0, 0)
# 说明:批量添加段落(复用样式对象)
start_time = time.time()
for i in range(100):
para = doc1.add_paragraph(f"段落 {i+1}")
run = para.add_run()
run.font.size = font_size
run.font.color.rgb = font_color
fast_time = time.time() - start_time
print(f" 复用样式对象:{fast_time:.4f} 秒")
# 说明:方法2:在循环内创建样式对象(不推荐)
doc2 = Document()
start_time = time.time()
for i in range(100):
para = doc2.add_paragraph(f"段落 {i+1}")
run = para.add_run()
# 说明:每次循环都创建新的样式对象(较慢)
run.font.size = Pt(12)
run.font.color.rgb = RGBColor(255, 0, 0)
slow_time = time.time() - start_time
print(f" 重复创建样式对象:{slow_time:.4f} 秒")
print(f" 提速:{slow_time/fast_time:.2f} 倍")
print("\n2. 批量操作,避免逐个单元格操作:")
# 说明:批量操作表格(推荐)
doc3 = Document()
table = doc3.add_table(rows=10, cols=5)
data = [[f"R{i} C{j}" for j in range(5)] for i in range(10)]
# 说明:批量填充数据
for row_idx, row_data in enumerate(data):
for col_idx, value in enumerate(row_data):
table.cell(row_idx, col_idx).text = value
print(" 批量填充表格数据完成")
print("\n3. 完成后及时保存和关闭:")
print(" doc.save('file.docx') # 保存后及时关闭文档")
print(" # 如果不再使用,让 Python 自动回收内存")