以下是优化后的代码,修复了剪贴板获取图片失败的问题,并确保 `temp_image_paths` 正确初始化,同时优化了 Excel 工作表名称的处理。
import os
import time
import win32com.client as win32
import win32clipboard
from PIL import Image, ImageGrab
def process_excel_files(image_output_folder, target_width_cm=28.8, target_height_cm=21.45):
# 换算为点值
target_width_points = target_width_cm * 28.346 * 0.954302868579053
target_height_points = target_height_cm * 28.346 * 0.978538812785388
# 创建 Excel 应用实例
excel = win32.Dispatch("Excel.Application")
excel.Visible = False
excel.DisplayAlerts = False
# 存储所有临时图片文件路径的列表
temp_image_paths = []
# 遍历目录下的所有 Excel 文件
for idx, file_name in enumerate(os.listdir(image_output_folder)):
if file_name.endswith(".xlsx"):
file_path = os.path.join(image_output_folder, file_name)
print(f"正在处理文件: {file_path}")
temp_image_path = None # 确保 temp_image_path 在每次处理前定义
try:
wb = excel.Workbooks.Open(file_path)
ws_main = wb.Sheets(1) # 使用索引访问第一个工作表
ws_photo = wb.Sheets(2) # 使用索引访问第二个工作表
print("成功打开文件")
except Exception as e:
print(f"打开文件时发生错误: {e}")
continue
# 1. 处理 A1:G19 区域
try:
ws_main.Range("A1:G19").CopyPicture(Format=win32.constants.xlPicture)
print("已复制图片区域 A1:G19 到剪贴板")
# 等待剪贴板加载,并尝试多次获取图片
image = None
for _ in range(5):
time.sleep(0.5)
image = ImageGrab.grabclipboard()
if image:
break
if image is None:
print("无法从剪贴板获取图片")
else:
# 将图片背景填充为白色
white_background = Image.new("RGB", image.size, (255, 255, 255))
white_background.paste(image, mask=image.split() if image.mode == 'RGBA' else None)
# 给临时图片添加唯一序号
temp_image_path = os.path.join(image_output_folder, f"temp_image_A1_G19_{idx}.png")
white_background.save(temp_image_path)
# 将该临时图片路径加入列表
temp_image_paths.append(temp_image_path)
# 插入图片到 A1 区域,设置图片大小为指定尺寸
ws_main.Shapes.AddPicture(
temp_image_path,
LinkToFile=False,
SaveWithDocument=True,
Left=ws_main.Range("A1").Left,
Top=ws_main.Range("A1").Top,
Width=target_width_points,
Height=target_height_points
)
print("A1:G19 区域图片已插入并调整为指定尺寸")
except Exception as e:
print(f"处理 A1:G19 区域时发生错误: {e}")
try:
folder_name, _ = os.path.splitext(file_name)
image_folder = os.path.join(image_output_folder, folder_name)
if os.path.exists(image_folder):
insert_image(ws_photo, image_folder)
print(f"{folder_name} 照片已插入")
else:
print(f"未找到图片文件夹: {image_folder}")
except Exception as e:
print(f"插入照片时出错: {e}")
try:
wb.Save()
print(f"文件 {file_name} 已保存")
wb.Close()
except Exception as e:
print(f"保存文件时发生错误: {e}")
# 在所有文件处理完成后统一删除临时图片文件
for temp_image_path in temp_image_paths:
if os.path.exists(temp_image_path):
os.remove(temp_image_path)
print(f"已删除临时图片文件: {temp_image_path}")
print("所有文件已处理完成。")
excel.Quit()
### **优化点**
1. **修复 `temp_image_paths` 未初始化的问题**
2. **使用 `Sheets(1)` 和 `Sheets(2)` 访问工作表,避免名称错误**
3. **增加剪贴板获取图片的重试机制,最多尝试 5 次**
4. **修复 `os.path.splitext(file_name)` 返回元组的问题**
5. **确保 `insert_image(ws_photo, image_folder)` 只在文件夹存在时调用**
这样可以提高代码的稳定性,减少剪贴板获取图片失败的情况。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 |