save as filename (letter + number) + 1

本文介绍了一段VBA代码,该代码用于在Excel中将当前工作簿的名字进行递增更新,例如从xyzhd000001.xlsm更新到xyzhd000002.xlsm。通过解析文件名并增加特定部分的数值实现这一目标。
Sub plusone()
    Dim fn As String: fn = Left(ActiveWorkbook.Name, Len(ActiveWorkbook.Name) - 5)
    Dim y As Integer: y = Right(fn, 6)
    [f2] = Left(fn, 5) & Left("0000000", Len("0000000") - Len(y)) & (y + 1)

End Sub

'filename: xyzhd000001.xlsm => xyzhd000002.xlsm

import os import tkinter as tk from tkinter import filedialog, messagebox, ttk from PIL import Image, ImageTk import threading import xlwings as xw import pythoncom class WPSImageInserter: def __init__(self, root): self.root = root self.root.title("WPS表格自由图片插入工具") self.root.geometry("900x1200") self.root.resizable(True, True) # 变量初始化 self.excel_file = tk.StringVar() self.image_folder = tk.StringVar() self.sheet_name_var = tk.StringVar(value="") self.start_cell_var = tk.StringVar(value="B19") # 起始单元格 self.end_cell_var = tk.StringVar(value="E22") # 结束单元格 self.status_var = tk.StringVar(value="准备就绪") self.processing = False self.all_image_files = [] # 所有图片文件 self.selected_image_files = [] # 选中的图片文件 self.sheet_names = [] # 存储工作表名称 self.preview_image = None # 预览图片对象 self.inserted_images = [] # 存储已插入的图片 self.create_widgets() def create_widgets(self): # 主框架 main_frame = ttk.Frame(self.root, padding="15") main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S)) # 配置行列权重 self.root.columnconfigure(0, weight=1) self.root.rowconfigure(0, weight=1) main_frame.columnconfigure(1, weight=1) main_frame.rowconfigure(11, weight=1) # 图片选择区域行 # 文件选择区域 ttk.Label(main_frame, text="WPS表格文件:", font=("Arial", 11)).grid( row=1, column=0, sticky=tk.W, pady=5) excel_frame = ttk.Frame(main_frame) excel_frame.grid(row=1, column=1, columnspan=3, sticky=(tk.W, tk.E), pady=5) excel_frame.columnconfigure(0, weight=1) excel_entry = ttk.Entry(excel_frame, textvariable=self.excel_file) excel_entry.grid(row=0, column=0, sticky=(tk.W, tk.E), padx=(0, 10)) ttk.Button(excel_frame, text="选择文件", command=self.browse_excel).grid(row=0, column=1) ttk.Label(main_frame, text="图片文件夹:", font=("Arial", 11)).grid( row=2, column=0, sticky=tk.W, pady=5) image_frame = ttk.Frame(main_frame) image_frame.grid(row=2, column=1, columnspan=3, sticky=(tk.W, tk.E), pady=5) image_frame.columnconfigure(0, weight=1) image_entry = ttk.Entry(image_frame, textvariable=self.image_folder) image_entry.grid(row=0, column=0, sticky=(tk.W, tk.E), padx=(0, 10)) ttk.Button(image_frame, text="选择文件夹", command=self.browse_image_folder).grid(row=0, column=1) # 工作表选择 ttk.Label(main_frame, text="选择工作表:", font=("Arial", 11)).grid( row=3, column=0, sticky=tk.W, pady=5) sheet_frame = ttk.Frame(main_frame) sheet_frame.grid(row=3, column=1, columnspan=3, sticky=(tk.W, tk.E), pady=5) sheet_frame.columnconfigure(0, weight=1) self.sheet_combo = ttk.Combobox(sheet_frame, textvariable=self.sheet_name_var, state="readonly") self.sheet_combo.grid(row=0, column=0, sticky=(tk.W, tk.E), padx=(0, 10)) ttk.Button(sheet_frame, text="刷新工作表", command=self.refresh_sheets).grid(row=0, column=1) # 插入区域设置 ttk.Label(main_frame, text="插入区域设置:", font=("Arial", 12, "bold")).grid( row=5, column=0, sticky=tk.W, columnspan=4, pady=(0, 10)) # 起始单元格 ttk.Label(main_frame, text="起始单元格:").grid(row=6, column=0, sticky=tk.W, pady=5) start_cell_entry = ttk.Entry(main_frame, textvariable=self.start_cell_var, width=10) start_cell_entry.grid(row=6, column=1, sticky=tk.W, pady=5) ttk.Label(main_frame, text="如: B19").grid(row=6, column=1, sticky=tk.W, padx=(80, 0), pady=5) # 结束单元格 ttk.Label(main_frame, text="结束单元格:").grid(row=6, column=2, sticky=tk.W, pady=5) end_cell_entry = ttk.Entry(main_frame, textvariable=self.end_cell_var, width=10) end_cell_entry.grid(row=6, column=3, sticky=tk.W, pady=5) ttk.Label(main_frame, text="如: E22").grid(row=6, column=3, sticky=tk.W, padx=(80, 0), pady=5) # 区域信息显示 self.area_info_var = tk.StringVar(value="区域信息将在这里显示") ttk.Label(main_frame, textvariable=self.area_info_var, font=("Arial", 10), foreground="blue").grid(row=7, column=0, columnspan=4, sticky=tk.W, pady=5) # 图片选择区域 ttk.Label(main_frame, text="图片选择 (按住Ctrl多选或双击预览):", font=("Arial", 12, "bold")).grid( row=16, column=0, sticky=tk.W, columnspan=4, pady=(0, 10)) # 创建左右分栏 selection_frame = ttk.Frame(main_frame) selection_frame.grid(row=11, column=0, columnspan=4, sticky=(tk.W, tk.E, tk.N, tk.S), pady=5) selection_frame.columnconfigure(0, weight=1) selection_frame.columnconfigure(1, weight=1) selection_frame.rowconfigure(0, weight=1) # 左侧:所有图片列表 - 增加高度 left_frame = ttk.LabelFrame(selection_frame, text="所有图片") left_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S), padx=(0, 10)) left_frame.columnconfigure(0, weight=1) left_frame.rowconfigure(0, weight=1) self.all_images_listbox = tk.Listbox(left_frame, selectmode=tk.MULTIPLE, font=("Consolas", 9), height=20) scrollbar_left = ttk.Scrollbar(left_frame, orient="vertical", command=self.all_images_listbox.yview) self.all_images_listbox.configure(yscrollcommand=scrollbar_left.set) self.all_images_listbox.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S)) scrollbar_left.grid(row=0, column=1, sticky=(tk.N, tk.S)) # 右侧:选中图片列表 - 增加高度 right_frame = ttk.LabelFrame(selection_frame, text="已选图片") right_frame.grid(row=0, column=1, sticky=(tk.W, tk.E, tk.N, tk.S), padx=(10, 0)) right_frame.columnconfigure(0, weight=1) right_frame.rowconfigure(0, weight=1) self.selected_images_listbox = tk.Listbox(right_frame, font=("Consolas", 9), height=20) scrollbar_right = ttk.Scrollbar(right_frame, orient="vertical", command=self.selected_images_listbox.yview) self.selected_images_listbox.configure(yscrollcommand=scrollbar_right.set) self.selected_images_listbox.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S)) scrollbar_right.grid(row=0, column=1, sticky=(tk.N, tk.S)) # 选择按钮 button_frame = ttk.Frame(selection_frame) button_frame.grid(row=1, column=0, columnspan=2, pady=10) ttk.Button(button_frame, text="全选", command=self.select_all).pack(side=tk.LEFT, padx=5) ttk.Button(button_frame, text="清除选择", command=self.clear_selection).pack(side=tk.LEFT, padx=5) ttk.Button(button_frame, text="上移", command=self.move_up).pack(side=tk.LEFT, padx=5) ttk.Button(button_frame, text="下移", command=self.move_down).pack(side=tk.LEFT, padx=5) ttk.Button(button_frame, text="移除选中", command=self.remove_selected).pack(side=tk.LEFT, padx=5) # 选项区域 ttk.Label(main_frame, text="插入选项:", font=("Arial", 12, "bold")).grid( row=13, column=0, sticky=tk.W, columnspan=4, pady=(0, 10)) self.keep_aspect_var = tk.BooleanVar(value=True) ttk.Checkbutton(main_frame, text="保持图片宽高比", variable=self.keep_aspect_var).grid( row=14, column=0, columnspan=2, sticky=tk.W, pady=3) self.backup_var = tk.BooleanVar(value=True) ttk.Checkbutton(main_frame, text="创建备份文件", variable=self.backup_var).grid( row=14, column=2, columnspan=2, sticky=tk.W, pady=3) # 图片预览区域 ttk.Label(main_frame, text="图片预览:", font=("Arial", 12, "bold")).grid( row=15, column=0, sticky=tk.W, columnspan=4, pady=(10, 5)) preview_frame = ttk.Frame(main_frame) preview_frame.grid(row=16, column=0, columnspan=4, sticky=(tk.W, tk.E), pady=5) # 预览画布 self.preview_canvas = tk.Canvas(preview_frame, width=200, height=150, bg="#f0f0f0", highlightthickness=1, highlightbackground="#cccccc") self.preview_canvas.pack(side=tk.LEFT, padx=(0, 20)) self.preview_canvas.create_text(100, 75, text="双击图片预览", fill="#666666") # 图片信息显示 self.preview_info = tk.Text(preview_frame, height=8, width=50, wrap=tk.WORD, font=("Consolas", 9), bg="#f8f8f8") scrollbar_preview = ttk.Scrollbar(preview_frame, orient="vertical", command=self.preview_info.yview) self.preview_info.configure(yscrollcommand=scrollbar_preview.set) self.preview_info.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) scrollbar_preview.pack(side=tk.RIGHT, fill=tk.Y) self.preview_info.insert("1.0", "双击左侧列表中的图片可在此预览\n图片信息将显示在这里") self.preview_info.configure(state="disabled") # 分隔线 separator4 = ttk.Separator(main_frame, orient="horizontal") separator4.grid(row=17, column=0, columnspan=4, sticky=(tk.W, tk.E), pady=15) # 插入信息区域 ttk.Label(main_frame, text="插入信息:", font=("Arial", 12, "bold")).grid( row=18, column=0, sticky=tk.W, columnspan=4, pady=(10, 5)) info_frame = ttk.Frame(main_frame) info_frame.grid(row=19, column=0, columnspan=4, sticky=(tk.W, tk.E), pady=5) info_frame.columnconfigure(0, weight=1) info_frame.rowconfigure(0, weight=1) self.selection_info = tk.Text(info_frame, height=8, width=80, wrap=tk.WORD, font=("Consolas", 9), bg="#f8f8f8") scrollbar_info = ttk.Scrollbar(info_frame, orient="vertical", command=self.selection_info.yview) self.selection_info.configure(yscrollcommand=scrollbar_info.set) self.selection_info.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S)) scrollbar_info.grid(row=0, column=1, sticky=(tk.N, tk.S)) self.selection_info.insert("1.0", "选中图片信息和插入顺序将在这里显示") self.selection_info.configure(state="disabled") # 绑定列表事件 self.all_images_listbox.bind('<<ListboxSelect>>', self.on_image_select) self.all_images_listbox.bind('<Double-Button-1>', self.preview_and_select_image) # 进度和控制区域 control_frame = ttk.Frame(main_frame) control_frame.grid(row=20, column=0, columnspan=4, sticky=(tk.W, tk.E), pady=10) self.progress = ttk.Progressbar(control_frame, orient="horizontal", mode="determinate") self.progress.pack(fill=tk.X, pady=5) status_label = ttk.Label(control_frame, textvariable=self.status_var) status_label.pack(pady=5) action_frame = ttk.Frame(control_frame) action_frame.pack(pady=15) self.start_button = ttk.Button(action_frame, text="开始插入图片", command=self.start_insertion) self.start_button.pack(side=tk.LEFT, padx=10) ttk.Button(action_frame, text="刷新图片列表", command=self.refresh_image_list).pack(side=tk.LEFT, padx=10) ttk.Button(action_frame, text="打开文件位置", command=self.open_file_location).pack(side=tk.LEFT, padx=10) ttk.Button(action_frame, text="退出", command=self.root.quit).pack(side=tk.LEFT, padx=10) # 配置权重 main_frame.rowconfigure(11, weight=1) # 图片选择区域行 main_frame.rowconfigure(19, weight=1) # 信息区域行 # 配置列表项颜色 self.all_images_listbox.tag_configure('selected', foreground='gray') def browse_excel(self): filetypes = [ ("Excel文件", "*.xlsx *.xls"), ("所有文件", "*.*") ] filename = filedialog.askopenfilename(title="选择WPS表格文件", filetypes=filetypes) if filename: self.excel_file.set(filename) self.status_var.set("表格文件已选择") self.refresh_sheets() def refresh_sheets(self): excel_file = self.excel_file.get() if excel_file and os.path.exists(excel_file): try: # 使用xlwings获取工作表名称 app = xw.App(visible=False) wb = app.books.open(excel_file) self.sheet_names = [sheet.name for sheet in wb.sheets] wb.close() app.quit() self.sheet_combo['values'] = self.sheet_names if self.sheet_names: self.sheet_name_var.set(self.sheet_names[0]) self.status_var.set(f"找到 {len(self.sheet_names)} 个工作表") else: self.status_var.set("未找到工作表") except Exception as e: messagebox.showerror("错误", f"读取工作表失败: {str(e)}") def browse_image_folder(self): folder = filedialog.askdirectory(title="选择图片文件夹") if folder: self.image_folder.set(folder) self.status_var.set("图片文件夹已选择") self.refresh_image_list() def refresh_image_list(self): folder = self.image_folder.get() if folder and os.path.exists(folder): supported_formats = ('.jpg', '.jpeg', '.png', '.bmp', '.tiff', '.webp') try: all_files = os.listdir(folder) self.all_image_files = [f for f in all_files if f.lower().endswith(supported_formats)] # 更新所有图片列表 self.all_images_listbox.delete(0, tk.END) for filename in self.all_image_files: self.all_images_listbox.insert(tk.END, filename) # 更新颜色 self.update_all_listbox_colors() self.update_area_info() self.update_selection_info() except Exception as e: messagebox.showerror("错误", f"读取文件夹错误: {e}") def update_all_listbox_colors(self): """更新所有图片列表的颜色,已选的置灰""" for i, filename in enumerate(self.all_image_files): if filename in self.selected_image_files: self.all_images_listbox.itemconfig(i, {'fg': 'gray'}) else: self.all_images_listbox.itemconfig(i, {'fg': 'black'}) def update_area_info(self): """更新区域信息""" start_cell = self.start_cell_var.get().strip() end_cell = self.end_cell_var.get().strip() if start_cell and end_cell: try: start_row, start_col = self.parse_cell_reference(start_cell) end_row, end_col = self.parse_cell_reference(end_cell) if start_row and end_row: rows = end_row - start_row + 1 cols = end_col - start_col + 1 total_cells = rows * cols info_text = f"区域: {start_cell}:{end_cell} | 行数: {rows} | 列数: {cols} | 总单元格: {total_cells}" self.area_info_var.set(info_text) return except: pass self.area_info_var.set("请输入有效的单元格区域") def on_image_select(self, event): """图片选择事件 - 单击预览""" selection = self.all_images_listbox.curselection() if selection: index = selection[0] image_path = os.path.join(self.image_folder.get(), self.all_image_files[index]) self.update_preview(image_path) self.show_preview_info(image_path) def preview_and_select_image(self, event): """双击预览并选中图片""" selection = self.all_images_listbox.curselection() if selection: index = selection[0] filename = self.all_image_files[index] # 添加到已选列表(如果尚未选中) if filename not in self.selected_image_files: self.selected_image_files.append(filename) self.selected_images_listbox.insert(tk.END, filename) # 更新列表颜色 self.update_all_listbox_colors() # 显示预览 image_path = os.path.join(self.image_folder.get(), filename) self.update_preview(image_path) self.show_preview_info(image_path) self.update_selection_info() def update_preview(self, image_path): """更新图片预览""" try: img = Image.open(image_path) # 保持宽高比进行缩放 img.thumbnail((180, 130), Image.LANCZOS) self.preview_image = ImageTk.PhotoImage(img) self.preview_canvas.delete("all") self.preview_canvas.create_image(100, 75, image=self.preview_image) except Exception as e: self.preview_canvas.delete("all") self.preview_canvas.create_text(100, 75, text="预览失败", fill="red") print(f"预览错误: {e}") def show_preview_info(self, image_path): """显示图片详细信息""" try: img = Image.open(image_path) filename = os.path.basename(image_path) file_size = os.path.getsize(image_path) / 1024 # KB file_size_str = f"{file_size:.1f} KB" if file_size < 1024 else f"{file_size / 1024:.1f} MB" info_text = f"文件名: {filename}\n" info_text += f"尺寸: {img.width} × {img.height} 像素\n" info_text += f"格式: {img.format}\n" info_text += f"大小: {file_size_str}\n" info_text += f"模式: {img.mode}\n" self.preview_info.configure(state="normal") self.preview_info.delete("1.0", "end") self.preview_info.insert("1.0", info_text) self.preview_info.configure(state="disabled") except Exception as e: self.preview_info.configure(state="normal") self.preview_info.delete("1.0", "end") self.preview_info.insert("1.0", f"无法读取图片信息: {str(e)}") self.preview_info.configure(state="disabled") def add_selected_images(self, event): """添加选中的图片到已选列表""" selection = self.all_images_listbox.curselection() for index in selection: filename = self.all_image_files[index] if filename not in self.selected_image_files: self.selected_image_files.append(filename) self.selected_images_listbox.insert(tk.END, filename) self.update_selection_info() def select_all(self): """全选所有图片""" self.selected_image_files = self.all_image_files.copy() self.selected_images_listbox.delete(0, tk.END) for filename in self.selected_image_files: self.selected_images_listbox.insert(tk.END, filename) # 更新列表颜色 self.update_all_listbox_colors() self.update_selection_info() def clear_selection(self): """清除所有选择""" self.selected_image_files = [] self.selected_images_listbox.delete(0, tk.END) # 更新列表颜色 self.update_all_listbox_colors() self.update_selection_info() def move_up(self): """上移选中图片""" selection = self.selected_images_listbox.curselection() if selection: index = selection[0] if index > 0: # 交换位置 self.selected_image_files[index], self.selected_image_files[index - 1] = \ self.selected_image_files[index - 1], self.selected_image_files[index] # 更新列表显示 self.update_selected_listbox() self.selected_images_listbox.select_set(index - 1) self.update_selection_info() def move_down(self): """下移选中图片""" selection = self.selected_images_listbox.curselection() if selection: index = selection[0] if index < len(self.selected_image_files) - 1: # 交换位置 self.selected_image_files[index], self.selected_image_files[index + 1] = \ self.selected_image_files[index + 1], self.selected_image_files[index] # 更新列表显示 self.update_selected_listbox() self.selected_images_listbox.select_set(index + 1) self.update_selection_info() def remove_selected(self): """移除选中的图片""" selection = self.selected_images_listbox.curselection() if selection: # 从后往前删除,避免索引变化 for index in sorted(selection, reverse=True): if 0 <= index < len(self.selected_image_files): del self.selected_image_files[index] self.update_selected_listbox() # 更新列表颜色 self.update_all_listbox_colors() self.update_selection_info() def update_selected_listbox(self): """更新已选图片列表显示""" self.selected_images_listbox.delete(0, tk.END) for filename in self.selected_image_files: self.selected_images_listbox.insert(tk.END, filename) def update_selection_info(self): """更新选择信息""" total_selected = len(self.selected_image_files) start_cell = self.start_cell_var.get().strip() end_cell = self.end_cell_var.get().strip() info_text = f"已选择 {total_selected} 张图片\n\n" if start_cell and end_cell: try: start_row, start_col = self.parse_cell_reference(start_cell) end_row, end_col = self.parse_cell_reference(end_cell) if start_row and end_row: rows = end_row - start_row + 1 cols = end_col - start_col + 1 total_cells = rows * cols info_text += f"插入区域: {start_cell}:{end_cell}\n" info_text += f"区域大小: {rows}行 × {cols}列 = {total_cells}个单元格\n\n" if total_selected > total_cells: info_text += f"⚠️ 警告: 选择了 {total_selected} 张图片,但区域只有 {total_cells} 个单元格\n" info_text += "多余的图片将不会被插入\n" elif total_selected < total_cells: info_text += f"提示: 选择了 {total_selected} 张图片,区域有 {total_cells} 个单元格\n" info_text += "剩余的单元格将保持空白\n" else: info_text += "✓ 图片数量与区域大小匹配\n" info_text += "\n插入顺序:\n" for i, filename in enumerate(self.selected_image_files): if i < total_cells: row = start_row + (i // cols) col = start_col + (i % cols) cell_ref = self.column_number_to_letter(col) + str(row) info_text += f"{i + 1:2d}. {filename} → {cell_ref}\n" else: info_text += f"{i + 1:2d}. {filename} (超出范围,不插入)\n" except Exception as e: print(f"错误: {e}") self.selection_info.configure(state="normal") self.selection_info.delete("1.0", "end") self.selection_info.insert("1.0", info_text) self.selection_info.configure(state="disabled") def parse_cell_reference(self, cell_ref): """解析单元格引用,返回行和列号""" import re match = re.match(r'^([A-Za-z]+)(\d+)$', cell_ref) if not match: return None, None col_letter = match.group(1).upper() row_number = int(match.group(2)) # 将列字母转换为列号 col_number = 0 for char in col_letter: col_number = col_number * 26 + (ord(char) - ord('A') + 1) return row_number, col_number def column_number_to_letter(self, n): """将列号转换为列字母""" result = "" while n > 0: n, remainder = divmod(n - 1, 26) result = chr(65 + remainder) + result return result def cm_to_points(self, cm): """将厘米转换为点""" return cm * 28.3465 def remove_inserted_images(self): """移除已插入的图片""" # 从所有图片列表中移除已插入的图片 for img in self.inserted_images: if img in self.all_image_files: self.all_image_files.remove(img) # 从已选图片列表中移除已插入的图片 for img in self.inserted_images: if img in self.selected_image_files: self.selected_image_files.remove(img) # 更新列表显示 self.all_images_listbox.delete(0, tk.END) for filename in self.all_image_files: self.all_images_listbox.insert(tk.END, filename) self.update_selected_listbox() # 更新颜色 self.update_all_listbox_colors() # 更新选择信息 self.update_selection_info() # 清空已插入图片列表 self.inserted_images = [] def start_insertion(self): if self.processing: return # 验证输入 excel_file = self.excel_file.get() image_folder = self.image_folder.get() sheet_name = self.sheet_name_var.get() start_cell = self.start_cell_var.get().strip() end_cell = self.end_cell_var.get().strip() if not excel_file or not os.path.exists(excel_file): messagebox.showerror("错误", "请选择有效的WPS表格文件!") return if not image_folder or not os.path.exists(image_folder): messagebox.showerror("错误", "请选择有效的图片文件夹!") return if not sheet_name: messagebox.showerror("错误", "请选择工作表!") return if not start_cell or not end_cell: messagebox.showerror("错误", "请输入起始和结束单元格!") return if not self.selected_image_files: messagebox.showerror("错误", "请选择要插入的图片!") return # 解析单元格区域 start_row, start_col = self.parse_cell_reference(start_cell) end_row, end_col = self.parse_cell_reference(end_cell) if not all([start_row, start_col, end_row, end_col]): messagebox.showerror("错误", "请输入有效的单元格引用!") return if start_row > end_row or start_col > end_col: messagebox.showerror("错误", "起始单元格必须在结束单元格的左上方!") return # 清空已插入图片列表 self.inserted_images = [] self.processing = True self.start_button.config(state="disabled") self.status_var.set("正在插入图片...") self.progress["value"] = 0 # 在新线程中处理 thread = threading.Thread( target=self.insert_images, args=(excel_file, image_folder, sheet_name, start_row, start_col, end_row, end_col) ) thread.daemon = True thread.start() def insert_images(self, excel_file, image_folder, sheet_name, start_row, start_col, end_row, end_col): try: # 创建备份文件 if self.backup_var.get(): backup_path = excel_file.replace('.xlsx', '_backup.xlsx').replace('.xls', '_backup.xls') import shutil shutil.copy2(excel_file, backup_path) self.root.after(0, lambda: self.update_status(f"已创建备份文件: {os.path.basename(backup_path)}")) # 初始化COM pythoncom.CoInitialize() # 打开Excel文件 self.root.after(0, lambda: self.update_status("正在打开WPS表格...")) app = xw.App(visible=False) wb = app.books.open(excel_file) # 选择指定的工作表 try: ws = wb.sheets[sheet_name] except: self.root.after(0, lambda: self.update_status(f"找不到工作表: {sheet_name}")) ws = wb.sheets[0] self.root.after(0, lambda: self.update_status(f"使用默认工作表: {ws.name}")) # 计算区域大小 rows = end_row - start_row + 1 cols = end_col - start_col + 1 total_cells = rows * cols # 转换厘米为点 width_points = self.cm_to_points(4.31) height_points = self.cm_to_points(7.37) # 插入图片 self.root.after(0, lambda: self.update_status("正在插入图片...")) inserted_count = 0 for i, filename in enumerate(self.selected_image_files): if i >= total_cells: break # 超出区域范围的图片不插入 image_path = os.path.join(image_folder, filename) # 计算目标单元格位置 cell_row = start_row + (i // cols) cell_col = start_col + (i % cols) target_cell = f"{self.column_number_to_letter(cell_col)}{cell_row}" try: # 获取目标单元格位置 cell_range = ws.range(target_cell) left = cell_range.left top = cell_range.top # 插入图片 pic = ws.pictures.add(image_path, left=left, top=top, width=width_points, height=height_points) # 保持宽高比 if self.keep_aspect_var.get(): pic.api.ShapeRange.LockAspectRatio = 1 inserted_count += 1 # 记录已插入的图片 self.inserted_images.append(filename) self.root.after(0, lambda idx=i, cell=target_cell: self.update_status(f"插入图片 {idx + 1} 到 {cell}")) progress = (i + 1) / min(len(self.selected_image_files), total_cells) * 100 self.root.after(0, lambda p=progress: self.progress.config(value=p)) except Exception as e: self.root.after(0, lambda: self.update_status(f"插入图片到 {target_cell} 失败: {str(e)}")) # 保存文件 self.root.after(0, lambda: self.update_status("正在保存文件...")) wb.save() wb.close() app.quit() pythoncom.CoUninitialize() self.root.after(0, lambda: self.update_status(f"完成!成功插入 {inserted_count} 张图片")) self.root.after(0, self.process_complete, True, inserted_count) except Exception as e: self.root.after(0, lambda: self.update_status(f"处理过程中出错: {str(e)}")) self.root.after(0, self.process_complete, False) try: pythoncom.CoUninitialize() except: pass def update_status(self, message): self.status_var.set(message) def process_complete(self, success, inserted_count=0): self.processing = False self.start_button.config(state="normal") if success: # 询问用户是否要删除已插入的图片 if messagebox.askyesno("完成", f"处理完成!\n成功插入 {inserted_count} 张图片\n" f"图片尺寸: 4.31cm × 7.37cm\n" f"插入区域: {self.start_cell_var.get()} 到 {self.end_cell_var.get()}\n\n" "是否从列表中移除已插入的图片?"): # 移除已插入的图片 self.remove_inserted_images() messagebox.showinfo("完成", f"已从列表中移除 {inserted_count} 张已插入的图片") else: messagebox.showerror("错误", "处理失败,请查看状态信息") def open_file_location(self): excel_file = self.excel_file.get() if excel_file and os.path.exists(excel_file): try: folder_path = os.path.dirname(excel_file) if os.name == 'nt': # Windows os.startfile(folder_path) elif os.name == 'posix': # macOS or Linux if os.uname().sysname == 'Darwin': # macOS os.system(f'open "{folder_path}"') else: # Linux os.system(f'xdg-open "{folder_path}"') except: messagebox.showerror("错误", "无法打开文件夹位置") else: messagebox.showerror("错误", "文件不存在") def main(): root = tk.Tk() app = WPSImageInserter(root) root.mainloop() if __name__ == "__main__": main() 找出错误并优化程序
最新发布
08-31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值