Python向Word文档插入图片并调整大小与位置
在自动化生成技术报告、数据分析汇总以及日常公文批处理的过程中,将数据图表或图片资源插入 Word(.docx)文档是一项非常普遍的操作。借助主流的 python-docx 库,我们可以通过简单的几行代码完成图片的载入、指定其物理显示尺寸,并结合段落与表格的排版属性精确设定图片在文档页面中的摆放位置。本文将以清晰的步骤拆解具体方法,提供直接可运行的示例代码与排版技巧。
一、准备工作与环境依赖安装
在 Python 生态中,处理 Word 格式(OpenXML 规范的 .docx 文件)最通用的工具是 python-docx。在开始编写代码前,需要确保已经在本地 Python 环境中安装了该核心库:
pip install python-docx
安装完成后,我们需要了解该库在排版图文时的对象层级关系:文档(Document)由多个段落(Paragraph)组成,段落内部包含若干文字运行块(Run)。在标准规范中,图片作为“行内形状(Inline Shape)”嵌入在 Run 对象内部,它的水平对齐和换行行为在默认情况下直接依附于其所属段落。
二、向文档插入图片的基础实现
插入图片可以通过两种常见方式进行:第一种是直接调用 Document.add_picture(),系统会自动在文档末尾追加一个全新段落并置入图片;第二种是先通过 doc.add_paragraph() 创建段落,再通过段落内的 Run.add_picture() 精确控制图片与前后文字的组合关系。
下面是直接插入图片的最基础代码:
from docx import Document
# 1. 初始化空白文档或打开现有文件
doc = Document()
# 2. 添加说明文字
doc.add_heading("数据分析报表", level=1)
doc.add_paragraph("下图为本季度各业务模块运行监控指标图:")
# 3. 插入图片(默认以原始物理尺寸插入)
doc.add_picture("chart.png")
# 4. 保存文档
doc.save("output_report.docx")
如果在调用 add_picture() 时没有指定任何尺寸参数,python-docx 会直接读取图片文件自身的 DPI(每英寸点数)和像素大小,并换算为文档内的物理宽高。若原图分辨率非常高,插入后图片可能会超出页面边界;若原图分辨率很低,插入后则可能过于细小。因此,在实际工程中,必须显式指定图片的宽度或高度。
三、精确控制图片大小与比例缩放
为了精确控制视觉尺寸,python-docx 在 docx.shared 模块中提供了完整的物理单位换算工具,包括英寸(Inches)、厘米(Cm)、毫米(Mm)以及排版常用的磅点(Pt)。
1. 保持长宽比的等比缩放(推荐)
在绝大多数排版场景中,我们希望图片保持原始长宽比,防止画面中的图表文字被压扁或拉长。要实现等比缩放,只需要传入 width 或 height 其中一个参数,Word 引擎在解析文档时会自动根据图片原生像素比例计算出未指定的另一维度:
from docx import Document
from docx.shared import Inches, Cm
doc = Document()
# 仅指定宽度为 4.5 英寸,高度将自动按比例计算
doc.add_picture("chart.png", width=Inches(4.5))
# 或者仅指定宽度为 12 厘米
doc.add_picture("chart.png", width=Cm(12.0))
doc.save("scaled_image.docx")
2. 强制指定宽高(固定尺寸)
如果业务有明确的统一框格要求(例如证件照或固定尺寸的图标位),可以同时传递 width 和 height:
from docx import Document
from docx.shared import Cm
doc = Document()
# 强制将图片尺寸设定为 6 厘米宽、4 厘米高(可能造成图像轻微变形)
doc.add_picture("badge.png", width=Cm(6.0), height=Cm(4.0))
doc.save("fixed_size.docx")
Inches 或 Cm 包装,而直接传入普通的整数 100,python-docx 会将其当作 100 EMU,渲染出来的图片仅有肉眼几乎无法察觉的微小黑点。
四、调整图片对齐位置与多图版式
在 Word 文档模型中,add_picture() 生成的对象默认是 InlineShape(行内图形)。行内图形本质上类似于一个尺寸较大的单字符,其水平排列受其所在宿主段落的文本对齐属性控制。
1. 单图居中与左右对齐
若要将图片在页面中居中,最规范的做法是:显式创建一个段落,将该段落的对齐属性设定为居中,随后在段落内部置入图片。需要导入 docx.enum.text.WD_PARAGRAPH_ALIGNMENT:
from docx import Document
from docx.shared import Inches
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
doc = Document()
# 1. 创建用于容纳图片的段落
p = doc.add_paragraph()
# 2. 设置段落水平居中对齐
p.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
# 3. 将图片添加到段落内
run = p.add_run()
run.add_picture("architecture.png", width=Inches(5.0))
# 4. 在其下方添加居中的图注文字
caption_p = doc.add_paragraph()
caption_p.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
caption_run = caption_p.add_run("图 1-1 系统整体架构示意图")
caption_run.font.size = Inches(0.12) # 设置较小字号
doc.save("centered_image.docx")
2. 多图并排排版(隐形表格容器法)
当需要将两张或多张图片在同一行并排显示(如方案对比或左右配图)时,直接插入两张图容易因为页宽限制导致自动折行。此时最稳健的做法是利用无边框的单行多列表格作为排版网格:
from docx import Document
from docx.shared import Inches
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.enum.table import WD_TABLE_ALIGNMENT
doc = Document()
# 创建 1 行 2 列的排版表格
table = doc.add_table(rows=1, cols=2)
table.alignment = WD_TABLE_ALIGNMENT.CENTER
# 在左单元格插入第一张图片并居中
cell_left = table.cell(0, 0)
p_left = cell_left.paragraphs[0]
p_left.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
p_left.add_run().add_picture("before.png", width=Inches(2.8))
# 在右单元格插入第二张图片并居中
cell_right = table.cell(0, 1)
p_right = cell_right.paragraphs[0]
p_right.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
p_right.add_run().add_picture("after.png", width=Inches(2.8))
doc.save("side_by_side.docx")
五、完整实战代码示例
将上述所有核心技术点串联,以下脚本展示了一个完整的端到端自动化文档生成过程,涵盖了居中题头图、正文等比图以及双图并排对比的组合实现:
import os
from pathlib import Path
from docx import Document
from docx.shared import Inches, Pt, RGBColor
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.enum.table import WD_TABLE_ALIGNMENT
def generate_illustrated_document(output_path: str):
doc = Document()
# 一、主标题
title_p = doc.add_paragraph()
title_p.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
title_run = title_p.add_run("系统性能监控月度审计报告")
title_run.font.size = Pt(20)
title_run.font.bold = True
title_run.font.color.rgb = RGBColor(0x33, 0x4E, 0x68)
# 二、正文导言
doc.add_paragraph("本报告汇集了核心集群近一个月的吞吐量与负载指标,重点包含峰值响应时间与资源占用情况。")
# 三、居中大图展示
img_center_path = "cluster_overview.png"
if os.path.exists(img_center_path):
p_img = doc.add_paragraph()
p_img.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
p_img.add_run().add_picture(img_center_path, width=Inches(5.5))
# 图注
p_cap = doc.add_paragraph()
p_cap.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
cap_run = p_cap.add_run("图 1:生产集群节点拓扑与负载分布概览")
cap_run.font.size = Pt(9.5)
cap_run.font.italic = True
# 四、双图对比栅格
doc.add_heading("优化前后对比分析", level=2)
t = doc.add_table(rows=1, cols=2)
t.alignment = WD_TABLE_ALIGNMENT.CENTER
img_a, img_b = "latency_before.png", "latency_after.png"
if os.path.exists(img_a) and os.path.exists(img_b):
cell_a, cell_b = t.cell(0, 0), t.cell(0, 1)
p_a = cell_a.paragraphs[0]
p_a.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
p_a.add_run().add_picture(img_a, width=Inches(2.7))
cell_a.add_paragraph("(a)优化前延迟分布").alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
p_b = cell_b.paragraphs[0]
p_b.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
p_b.add_run().add_picture(img_b, width=Inches(2.7))
cell_b.add_paragraph("(b)优化后延迟分布").alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
# 五、保存最终文档
doc.save(output_path)
print(f"文档已成功写入目标路径:{output_path}")
if __name__ == "__main__":
generate_illustrated_document("Final_Report.docx")
六、常见问题与排查要点
在实际执行自动化排版脚本时,开发者常会遇到以下几类典型问题:
- 找不到图片文件(FileNotFoundError):相对路径容易因工作目录变动而失效。建议在读取图片时,使用
pathlib.Path(__file__).resolve().parent / "images" / "pic.png"构建绝对路径,确保文件解析稳定。 - 图片尺寸过大或缩成极小黑点:直接给参数传入未经单位包装的整数值(如
width=300),导致 Word 按 EMU 解析。务必使用Inches()、Cm()或Pt()显式指定。 - 文字环绕与自由浮动定位限制:
python-docx官方原生接口仅支持“嵌入型/行内”图片排版,不原生提供“衬于文字下方”或“紧密环绕”等浮动图片接口。如需精确定位坐标,可通过无边框表格、行首缩进(paragraph_format.left_indent)以及段落前后间距进行排版微调。
七、总结
通过 python-docx 操作 Word 中的图片并不复杂。核心关键在于两点:其一是理解尺寸单位模块 docx.shared,通过单向设置宽度实现不失真的等比缩放;其二是理解行内图片与段落容器的依附关系,通过设置段落的 alignment 属性或利用无边框表格,灵活实现单图居中、左右排布以及多图并列的规范排版效果。掌握这些要点后,即可自如构建出专业、整洁的自动化图文报告。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









