
2.png (23.93 KB, 下载次数: 0)
下载附件
2025-5-26 13:28 上传
[Python] 纯文本查看 复制代码import tkinter as tk
from tkinter import ttk, filedialog, messagebox
from docx import Document
from docx.shared import Cm, Pt
from docx.enum.section import WD_ORIENT
from docx.enum.table import WD_ROW_HEIGHT
from docx.enum.text import WD_ALIGN_PARAGRAPH
from PIL import Image
import os
import glob
import platform
import subprocess
PAPER_SIZES = {
'A4纵向': (21.0, 29.7),
'A4横向': (29.7, 21.0),
'A3纵向': (29.7, 42.0),
'A3横向': (42.0, 29.7),
'Letter纵向': (21.59, 27.94),
'Letter横向': (27.94, 21.59),
}
class ImageToWordApp:
def __init__(self, root):
self.root = root
self.root.title("Word快速插入图片工具")
# 变量初始化
self.auto_adjust = tk.BooleanVar(value=True)
self.show_filename = tk.BooleanVar(value=False)
# 创建界面组件
self.create_widgets()
def create_widgets(self):
# 图片文件夹选择
ttk.Label(self.root, text="图片文件夹:").grid(row=0, column=0, padx=5, pady=5, sticky='w')
self.image_folder_entry = ttk.Entry(self.root, width=40)
self.image_folder_entry.grid(row=0, column=1, padx=5, pady=5)
ttk.Button(self.root, text="浏览...", command=self.select_image_folder).grid(row=0, column=2, padx=5, pady=5)
# 输出文件选择
ttk.Label(self.root, text="输出文件:").grid(row=1, column=0, padx=5, pady=5, sticky='w')
self.output_file_entry = ttk.Entry(self.root, width=40)
self.output_file_entry.grid(row=1, column=1, padx=5, pady=5)
ttk.Button(self.root, text="浏览...", command=self.select_output_file).grid(row=1, column=2, padx=5, pady=5)
# 每行图片数量
ttk.Label(self.root, text="每行图片数量:").grid(row=2, column=0, padx=5, pady=5, sticky='w')
self.images_per_row = ttk.Spinbox(self.root, from_=1, to=10, width=5)
self.images_per_row.set(3)
self.images_per_row.grid(row=2, column=1, padx=5, pady=5, sticky='w')
# 纸张类型选择
ttk.Label(self.root, text="纸张类型:").grid(row=3, column=0, padx=5, pady=5, sticky='w')
self.paper_type = ttk.Combobox(self.root, values=list(PAPER_SIZES.keys()), width=15)
self.paper_type.current(0)
self.paper_type.grid(row=3, column=1, padx=5, pady=5, sticky='w')
# 行距设置
ttk.Label(self.root, text="行间距(cm):").grid(row=4, column=0, padx=5, pady=5, sticky='w')
self.row_spacing_entry = ttk.Entry(self.root, width=8)
self.row_spacing_entry.grid(row=4, column=1, padx=5, pady=5, sticky='w')
# 显示文件名选项
ttk.Checkbutton(
self.root, text="在图片下方显示文件名", variable=self.show_filename
).grid(row=5, column=0, padx=5, pady=5, sticky='w')
# 自动调整尺寸
self.auto_adjust_check = ttk.Checkbutton(
self.root, text="自动调整图片尺寸", variable=self.auto_adjust, command=self.toggle_manual_size)
self.auto_adjust_check.grid(row=6, column=0, columnspan=3, padx=5, pady=5, sticky='w')
# 手动尺寸输入
self.manual_size_frame = ttk.Frame(self.root)
ttk.Label(self.manual_size_frame, text="宽度(cm):").grid(row=0, column=0, padx=5)
self.manual_width = ttk.Entry(self.manual_size_frame, width=8)
self.manual_width.grid(row=0, column=1, padx=5)
ttk.Label(self.manual_size_frame, text="高度(cm):").grid(row=0, column=2, padx=5)
self.manual_height = ttk.Entry(self.manual_size_frame, width=8)
self.manual_height.grid(row=0, column=3, padx=5)
self.manual_size_frame.grid(row=7, column=0, columnspan=3, padx=5, pady=5, sticky='w')
self.manual_size_frame.grid_remove()
# 处理按钮
ttk.Button(self.root, text="开始处理", command=self.process_images).grid(row=8, column=1, pady=10)
def select_image_folder(self):
folder = filedialog.askdirectory()
if folder:
self.image_folder_entry.delete(0, tk.END)
self.image_folder_entry.insert(0, folder)
def select_output_file(self):
filepath = filedialog.asksaveasfilename(
defaultextension='.docx',
filetypes=[('Word文档', '*.docx')]
)
if filepath:
self.output_file_entry.delete(0, tk.END)
self.output_file_entry.insert(0, filepath)
def toggle_manual_size(self):
if self.auto_adjust.get():
self.manual_size_frame.grid_remove()
else:
self.manual_size_frame.grid()
def process_images(self):
# 获取输入参数
image_folder = self.image_folder_entry.get()
output_file = self.output_file_entry.get()
per_row = int(self.images_per_row.get())
paper_type = self.paper_type.get()
auto_adjust = self.auto_adjust.get()
show_filename = self.show_filename.get()
# 获取行间距
try:
row_spacing = float(self.row_spacing_entry.get()) if self.row_spacing_entry.get() else 0
except ValueError:
messagebox.showerror("错误", "请输入有效的行距数值")
return
# 参数验证
if not image_folder or not os.path.isdir(image_folder):
messagebox.showerror("错误", "请选择有效的图片文件夹")
return
if not output_file:
messagebox.showerror("错误", "请指定输出文件路径")
return
# 获取图片列表
image_extensions = ['*.jpg', '*.jpeg', '*.png', '*.bmp', '*.gif']
image_paths = []
for ext in image_extensions:
image_paths.extend(glob.glob(os.path.join(image_folder, ext)))
if not image_paths:
messagebox.showerror("错误", "图片文件夹中没有支持的图片文件")
return
try:
# 创建Word文档
doc = Document()
# 设置页面大小
paper_size = PAPER_SIZES[paper_type]
section = doc.sections[0]
section.page_width = Cm(paper_size[0])
section.page_height = Cm(paper_size[1])
# 设置默认页边距(左右各2cm)
section.left_margin = Cm(2)
section.right_margin = Cm(2)
# 计算可用宽度
available_width = paper_size[0] - 4 # 左右边距各2cm
# 处理图片尺寸
if auto_adjust:
image_width = available_width / per_row
# 获取最大高度比例
max_height = 0
for img_path in image_paths:
with Image.open(img_path) as img:
w, h = img.size
aspect_ratio = h / w
height = image_width * aspect_ratio
if height > max_height:
max_height = height
image_height = max_height
else:
try:
image_width = float(self.manual_width.get())
image_height = float(self.manual_height.get())
except ValueError:
messagebox.showerror("错误", "请输入有效的尺寸数值")
return
# 创建表格
table = doc.add_table(rows=0, cols=per_row)
# 插入图片
for i, img_path in enumerate(sorted(image_paths)):
if i % per_row == 0:
row = table.add_row()
# 设置行高
if row_spacing > 0:
row.height = Cm(row_spacing)
row.height_rule = WD_ROW_HEIGHT.EXACTLY
cell = row.cells[i % per_row]
# 添加图片段落
img_paragraph = cell.paragraphs[0]
img_paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
try:
run = img_paragraph.add_run()
run.add_picture(img_path, width=Cm(image_width), height=Cm(image_height))
except Exception as e:
messagebox.showwarning("警告", f"无法加载图片:{os.path.basename(img_path)}\n{str(e)}")
# 添加文件名
if show_filename:
# 创建新段落
name_paragraph = cell.add_paragraph()
name_paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
# 设置字体样式
run = name_paragraph.add_run(os.path.splitext(os.path.basename(img_path))[0])
font = run.font
font.size = Pt(9)
font.name = '宋体'
# 保存文档
doc.save(output_file)
# 自动打开文档
self.open_file(output_file)
messagebox.showinfo("完成", "文档生成成功!")
except Exception as e:
messagebox.showerror("错误", f"处理过程中发生错误:\n{str(e)}")
def open_file(self, path):
try:
if platform.system() == 'Windows':
os.startfile(path)
elif platform.system() == 'Darwin':
subprocess.run(['open', path])
else:
subprocess.run(['xdg-open', path])
except Exception as e:
messagebox.showwarning("警告", f"无法自动打开文件:{str(e)}")
if __name__ == '__main__':
root = tk.Tk()
app = ImageToWordApp(root)
root.mainloop()