吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]
查看: 4279|回复: 54
收起左侧

[Python 原创] 快速将图片插入到word文件中

  [复制链接]
wjgboy 发表于 2025-5-26 13:26
本帖最后由 wjgboy 于 2025-6-30 19:02 编辑

最近经常要将各种大小的图片插入到word文件中,导致排版很不方面。今天结合DS写了以下代码。

2.png
[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()


成品链接:https://wwes.lanzoub.com/iW6Vf2zyjzhi

免费评分

参与人数 9吾爱币 +11 热心值 +8 收起 理由
h07799486 + 1 + 1 谢谢@Thanks!
3622020 + 1 + 1 热心回复!
wuyongkui + 1 + 1 谢谢@Thanks!
苏紫方璇 + 3 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
rxnwin + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
kymql24 + 1 + 1 谢谢@Thanks!
wa80000 + 1 + 1 我很赞同!
GXW1693 + 1 + 1 热心回复!
lijun888 + 1 谢谢@Thanks!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

wuyongkui 发表于 2025-6-6 16:16
大侠,我的是Win7系统,提示Error
Failed to load Python DLL
'C:\Users\AdministratorAppDataLocal\Temp_MEI24882\python3
13.dl'.
LoadLibrary: 找不到指定的模块,
确定
咋办呢啊?谢谢您啦
netdna518 发表于 2025-5-28 11:26
很好用!希望作者加个功能:
选择插入图片的顺序:
按图片属性里面的修改时间升序/降序;
按图片大小升序/降序;
按图片名称升序/降序;
leonas30200 发表于 2025-5-26 13:44
51cbb 发表于 2025-5-26 13:57
收藏备用!
Qodd 发表于 2025-5-26 14:00
mark一下
mmdg13142 发表于 2025-5-26 14:22
放个屁股,感觉有用
一只哈巴狗哟 发表于 2025-5-26 14:23
没有程序下载亚
onetwo888 发表于 2025-5-26 14:27
好东西需要收藏!!
GXW1693 发表于 2025-5-26 14:37
下载链接?
gao887 发表于 2025-5-26 15:08
不是成品不会用纯小白,等大神的安装文件
GXW1693 发表于 2025-5-26 15:29
第一张图的成品在那里下载?
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-7-21 21:43

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表