快速将图片插入到word文件中

查看 16|回复 1
作者:wjgboy   
最近经常要将各种大小的图片插入到word文件中,导致排版很不方面。今天结合DS写了以下代码。


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()

图片, 文件

leonas30200   

先收藏  说不定哪天就用上啦
您需要登录后才可以回帖 登录 | 立即注册

返回顶部