图片插入word的相关工作。
但还是需要一些其他的功能,于是做了一些扩展。
原贴地址:
python批量插入图片到word文档里并且实现分栏排版 - 吾爱破解 - 52pojie.cn以及11楼hfol85大佬的源码
现在支持如下功能:
图片导入:支持文件夹扫描或手动选择多个图片
排版设置:每页 1~8 张图可选,支持横向/纵向页面
文件名显示:可选择是否显示、是否包含扩展名
样式控制:表格居中、图片居中、行高固定、边距控制
文档保存:自动生成.docx并提示保存位置
支持插入:
纵向页面:每页1张 每页2张 每页4张 每页6张 每页8张
横向页面:每页1张 每页2张 每页4张 每页6张 每页8张
打包的exe地址:https://pan.baidu.com/s/16ZgH7K0N24kdB0cwyvU-lw?pwd=52pj

纵向-显示文件名-带后缀-每页8张.png (247.61 KB, 下载次数: 1)
下载附件
2025-8-15 15:52 上传

横向-显示文件名-不带后缀-每页一张.jpg (128.25 KB, 下载次数: 1)
下载附件
2025-8-15 15:52 上传

程序界面.jpg (45.02 KB, 下载次数: 3)
下载附件
2025-8-15 15:52 上传
源码如下,可根据自己的实际需求微调:
[Python] 纯文本查看 复制代码import tkinter as tk
from tkinter import filedialog
from docx import Document
from docx.shared import Inches, Cm
from docx.enum.table import WD_TABLE_ALIGNMENT
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.oxml.shared import OxmlElement, qn
import os
def get_folder_path():
folder_selected = filedialog.askdirectory()
folder_path.set(folder_selected)
selected_files.set("")
def get_output_file_path():
output_file_selected = filedialog.asksaveasfilename(
defaultextension=".docx",
filetypes=[("Word文档", "*.docx"), ("所有文件", "*.*")],
title="选择输出文件的位置和名称"
)
output_filename.set(output_file_selected)
def select_files():
files_selected = filedialog.askopenfilenames(
title="选择图片文件",
filetypes=[("图片文件", "*.jpg *.jpeg *.png *.JPG *.JPEG *.PNG"), ("所有文件", "*.*")]
)
if files_selected:
selected_files.set(";".join(files_selected))
folder_path.set("")
def set_cell_margins(cell, **kwargs):
tc = cell._tc
tcPr = tc.get_or_add_tcPr()
tcMar = OxmlElement('w:tcMar')
for marge, value in kwargs.items():
node = OxmlElement("w:{}".format(marge))
node.set(qn('w:w'), str(value))
node.set(qn('w:type'), 'dxa')
tcMar.append(node)
tcPr.append(tcMar)
def set_row_height(row, height_cm):
tr = row._tr
trPr = tr.get_or_add_trPr()
height_element = OxmlElement('w:trHeight')
height_element.set(qn('w:val'), str(int(height_cm * 567)))
height_element.set(qn('w:hRule'), 'exact')
trPr.append(height_element)
def replace_paragraph_marks(doc):
paragraphs_to_remove = []
for paragraph in doc.paragraphs:
if not paragraph.text.strip() and len(paragraph.runs) == 0:
paragraphs_to_remove.append(paragraph)
for paragraph in reversed(paragraphs_to_remove):
p = paragraph._element
p.getparent().remove(p)
def create_document():
img_folder = folder_path.get()
files_list = selected_files.get()
output_file = output_filename.get()
show_filename = show_filename_var.get()
include_extension = include_extension_var.get()
orientation = orientation_var.get()
images_per_page = images_per_page_var.get()
image_paths = []
if img_folder:
image_paths = [os.path.join(img_folder, f) for f in os.listdir(img_folder) if f.lower().endswith(('.jpg', '.jpeg', '.png'))]
elif files_list:
image_paths = files_list.split(";")
image_paths = [f for f in image_paths if f.lower().endswith(('.jpg', '.jpeg', '.png'))]
else:
status_label.config(text='请先选择图片文件夹或选择图片文件。')
return
if not output_file:
status_label.config(text='请先选择输出文件的位置和名称。')
return
if not image_paths:
status_label.config(text='没有找到支持的图片格式。')
return
status_label.config(text='正在创建文档...')
window.update()
doc = Document()
if orientation == "横向":
section = doc.sections[0]
section.orientation = 1
new_width = section.page_height
new_height = section.page_width
section.page_width = new_width
section.page_height = new_height
vertical_rules = {
1: {"rows": 1, "cols": 1, "row_height": 22.0, "max_width": Cm(15.0)},
2: {"rows": 2, "cols": 1, "row_height": 11.0, "max_width": Cm(15.0)},
4: {"rows": 2, "cols": 2, "row_height": 11.0, "max_width": Cm(7.0)},
6: {"rows": 3, "cols": 2, "row_height": 7.3, "max_width": Cm(7.0)},
8: {"rows": 4, "cols": 2, "row_height": 5.3, "max_width": Cm(7.0)}
}
horizontal_rules = {
1: {"rows": 1, "cols": 1, "row_height": 16.0, "max_width": Cm(20.0)},
2: {"rows": 2, "cols": 1, "row_height": 8.0, "max_width": Cm(20.0)},
4: {"rows": 2, "cols": 2, "row_height": 8.0, "max_width": Cm(10.0)},
6: {"rows": 3, "cols": 2, "row_height": 5.3, "max_width": Cm(10.0)},
8: {"rows": 4, "cols": 2, "row_height": 4.0, "max_width": Cm(10.0)}
}
if orientation == "纵向":
rules = vertical_rules
else:
rules = horizontal_rules
if images_per_page not in rules:
status_label.config(text='无效的每页图片数量选择。')
return
current_rule = rules[images_per_page]
rows_per_page = current_rule["rows"]
cols_per_page = current_rule["cols"]
row_height = current_rule["row_height"]
max_width = current_rule["max_width"]
for page_start in range(0, len(image_paths), images_per_page):
table = doc.add_table(rows=rows_per_page, cols=cols_per_page)
table.alignment = WD_TABLE_ALIGNMENT.CENTER
for row in table.rows:
set_row_height(row, row_height)
for cell in row.cells:
cell.vertical_alignment = 1
set_cell_margins(cell, top=50, bottom=50, left=50, right=50)
page_images = image_paths[page_start:page_start + images_per_page]
for i, img_path in enumerate(page_images):
row_idx = i // cols_per_page
col_idx = i % cols_per_page
if row_idx available_height:
scale_ratio = available_height / pic.height.cm
new_width = pic.width.cm * scale_ratio
pic.width = Cm(new_width)
pic.height = Cm(available_height)
if show_filename:
filename = os.path.basename(img_path)
if not include_extension:
filename = os.path.splitext(filename)[0]
filename_para = cell.add_paragraph()
filename_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
filename_run = filename_para.add_run(filename)
filename_run.font.name = 'Times New Roman'
filename_run._element.rPr.rFonts.set(qn('w:eastAsia'), '宋体')
from docx.shared import Pt
filename_run.font.size = Pt(10.5)
status_label.config(text=f'{os.path.basename(img_path)} 已插入到 word 文档中...')
window.update()
except Exception as e:
status_label.config(text=f'无法插入 {os.path.basename(img_path)},原因:{e}')
window.update()
if page_start + images_per_page