导航菜单

  • 1.vector
  • 2.milvus
  • 3.pymilvus
  • 4.rag
  • 5.rag_measure
  • 7.search
  • ragflow
  • heapq
  • HNSW
  • cosine_similarity
  • math
  • typing
  • etcd
  • minio
  • collections
  • jieba
  • random
  • beautifulsoup4
  • chromadb
  • sentence_transformers
  • numpy
  • lxml
  • openpyxl
  • PyMuPDF
  • python-docx
  • requests
  • python-pptx
  • text_splitter
  • all-MiniLM-L6-v2
  • openai
  • llm
  • BPETokenizer
  • Flask
  • RAGAS
  • BagofWords
  • langchain
  • Pydantic
  • abc
  • faiss
  • MMR
  • scikit-learn
  • 1. 什么是 python-docx?
  • 2. 环境准备
    • 2.1 检查 Python 版本
    • 2.2 安装 python-docx
    • 2.3 验证安装
  • 3. 核心概念
    • 3.1 Document(文档对象)
    • 3.2 Paragraph(段落对象)
    • 3.3 Run(文本片段对象)
    • 3.4 Table(表格对象)
  • 4. 快速体验:创建和读取文档
    • 4.1 创建 Word 文档
    • 4.2 读取 Word 文档
  • 5. 创建和读取文档:详细操作
    • 5.1 创建文档并添加内容
    • 5.2 读取文档内容
  • 6. 段落和样式:文本格式化
    • 6.1 段落和 Run
    • 6.2 段落对齐和间距
  • 7. 标题和列表:组织文档结构
    • 7.1 添加标题
    • 7.2 添加列表
  • 8. 表格操作:创建和填充表格
    • 8.1 创建表格并填充数据
    • 8.2 设置列宽和合并单元格
  • 9. 图片插入:在文档中添加图片
    • 9.1 插入图片
    • 9.2 插入多张图片
  • 10. 页面设置:页眉页脚和页面布局
    • 10.1 设置页面布局
    • 10.2 添加页眉页脚
  • 11. 实战案例:批量生成文档
    • 11.1 批量生成合同
  • 12. 常见问题与排查
    • 12.1 中文字体显示问题
    • 12.2 文件损坏问题
    • 12.3 图片路径问题
    • 12.4 性能优化建议
  • 13. 参考

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 --version

2.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 自动回收内存")

13. 参考 #

  • python-docx 官方文档
  • python-docx GitHub
  • OpenPyXL 教程
  • Pandas 教程

访问验证

请输入访问令牌

Token不正确,请重新输入