Python 将多张图片插入到excel中并统一设置大小

Python 将多张图片插入到excel中并统一设置大小

1.任务目标

我的一个闺蜜是开珠宝工作室的,她让我给她做一个珠宝出入库登记表。
珠宝图片有100多张,图片分别存在三个文件夹。
第1个文件夹有94张图片,第2个文件夹有40张图片,第3个文件夹有15张图片。
诉求是每张图片的尺寸不一样,她希望存放到文件夹里图片的尺寸大小是一样的。

2.准备工作

1)新建文件夹【珪玥珠宝】。
2)在【珪玥珠宝】文件夹中新建三个文件夹,分别命名为【images1】【images2】【images3】。
3)将要处理的图片分别存放到【images1】【images2】【images3】文件夹中。
4)对【images1】【images2】【images3】文件夹里的图片进行重命名。
5)在【珪玥珠宝】文件夹中新建1个excel文件,命名为【珪玥珠宝库存表.xlsx】。
5)用vscode 编辑器打开【珪玥珠宝】文件夹,并在该文件夹下新建一个.py或.ipynb文件。

重命名方法

1)全选照片:【ctrl】+【A】。
2)按【F2】,第一张图片的名称会变为蓝色。
3)输入字【图】后按回车。

得到的图片如下图所示:

在这里插入图片描述

重复上面的动作,将三个文件夹里的图片的名字都进行重命名。
重命名的目的是用数字排序,方便后面的循环插入图片。

【温馨提示】
注意一个文件夹里的图片类型必须一致。
可以都是【.jpn】。
可以都是【.jpeg】。

根据需要设置Excel

在这里插入图片描述

相对路径的获取方法

鼠标右键点击【图片(1)】。
【复制相对路径】。
注意区分路径中的括号是英文输入法下输入的。

在这里插入图片描述

3.实操练习

1.插入一张图片

# import 库名 导入库
import openpyxl

# 打开刚才新建的工作薄
# wb对象= 库名.方法(path)
# load_workbook是openpyxl的方法,作用是打开工作薄
# path='珪玥珠宝库存表.xlsx'
# 这里的path 是相对路径
wb=openpyxl.load_workbook('珪玥珠宝库存表.xlsx')

# 工作薄里有3个工作表【图1】【图2】【图3】    
# wb对象[工作表名]确定要插入的工作表
# 我这里先往【图3】工作表中插入图片
ws=wb['图库3']

# 自定义【图3】工作表第3行的高度
# 第一张图片要插入的位置是B3(B列,第3行)
# 工作表对象有row_dimensions 和column_dimensions属性,可以控制行高和列宽。
# ws对象.row_dimensions[行]高=值
ws.row_dimensions[3].height=80

# 根据指定的图像文件创建img图像
# img对象=库名.drawing.image.Image(path)
# 注意第1个image的i是小写
# 注意第2个Image的I是大写
# path = 'images3\图 (1).jpeg'
# path 是图 (1)的相对路径
img=openpyxl.drawing.image.Image('images3\图 (1).jpeg')

# 设置图片的宽度
# 图片对象.width  = 值
img.width  = 114

# 设置图片的高度
# 图片对象.height  = 值
img.height = 101

# 在B3单元格中添加img图像
ws.add_image(img,'B3')

# 图片插入后将工作薄另存为'结果表1—珪玥珠宝库存表.xlsx'
wb.save('结果表1—珪玥珠宝库存表.xlsx')  

# 加一个输出,验证程序运行是否有错误
print('程序结束!')

【终端输出】

程序结束!
<think>我们有两个主要任务:1. 缩小图片尺寸;2. 将缩小后的图片插入Excel的指定sheet的指定位置。 根据引用[1]、[2]、[3],我们可以使用openpyxl库来操作Excel使用PIL(Python Imaging Library)或openpyxl的Image类来处理图片。 引用[1]和[3]中使用了openpyxl.drawing.image.Image来插入图片设置图片的width和height属性来调整大小。 引用[1]还提到了设置单元格的宽度和高度,以确保图片能适应单元格。 步骤: 1. 安装必要的库:openpyxl和Pillow(用于处理图片,因为openpyxl的Image类需要Pillow库支持) 如果还没有安装,可以使用以下命令安装: pip install openpyxl Pillow 2. 加载工作簿和指定的工作表。 3. 调整目标单元格的大小(可选,但推荐,以便图片能适应单元格)。 4. 加载图片,调整图片尺寸(通过设置Image对象的width和height属性)。 5.图片添加到工作表的指定单元格(例如'D3')。 6. 保存工作簿。 注意:在调整图片大小时,我们有两种方式: a. 使用PIL打开图片调整大小,然后保存为一个临时文件,再用openpyxl加载这个临时文件。 b. 直接使用openpyxl的Image类加载原始图片,然后设置其width和height属性(如引用[1]和[3]所示)。这种方式不会改变图片的宽高比,但可能会拉伸图片(因为只是设置了显示的宽高,没有进行裁剪等操作)。如果希望保持宽高比,需要自己计算比例。 但是,根据引用[1]和[3]的示例,他们直接设置了width和height,这样图片会按照设置的尺寸显示,可能会变形。如果我们希望保持宽高比,可以只设置一个维度(宽或高),另一个根据比例计算,或者使用PIL先进行等比例缩放,然后创建一个新的图片对象,再插入。 这里我们提供两种方法: 方法一:使用openpyxl直接设置图片尺寸(不保持宽高比,简单快速,但可能变形) 方法二:使用PIL先调整图片大小(保持宽高比),然后插入(需要临时文件或使用内存流,稍复杂) 由于引用中都是直接设置,且用户没有特别要求保持宽高比,我们可以先按直接设置的方法(方法一)实现。如果用户需要保持宽高比,我们再提供方法二。 下面我们按照方法一(直接设置)来写代码,同时给出方法二(保持宽高比)的代码作为备选。 方法一:不保持宽高比(直接设置) 示例代码: """ import openpyxl from openpyxl.drawing.image import Image # 加载工作簿,如果不存在则创建 try: workbook = openpyxl.load_workbook('我的数据.xlsx') except FileNotFoundError: workbook = openpyxl.Workbook() # 选择或创建sheet sheet_name = "我的数据" if sheet_name in workbook.sheetnames: sheet = workbook[sheet_name] else: sheet = workbook.create_sheet(title=sheet_name, index=0) # 设置单元格的尺寸(可选,但推荐设置,以便图片能适应单元格) column_letter = 'D' # 列号 row_number = 3 # 行号 column_width = 12.25 # 列宽(单位是字符宽度的近似值) row_height = 80.10 # 行高(单位是磅) sheet.column_dimensions[column_letter].width = column_width sheet.row_dimensions[row_number].height = row_height # 加载图片 img_path = './0fc62dc1d223455794c475c70f041737躯干.jpg' img = Image(img_path) # 设置图片尺寸(单位:像素?注意:openpyxl中设置的是显示尺寸,单位是Excel中的单位,与像素不是1:1,但可以按需调整) # 这里我们设置成和单元格差不多的大小 img.width = 90 img.height = 90 # 将图片添加到单元格(注意:add_image方法需要指定锚点,例如'D3') sheet.add_image(img, f'{column_letter}{row_number}') # 保存工作簿 workbook.save('我的数据.xlsx') """ 方法二:使用PIL保持宽高比调整图片大小,然后插入 步骤: 1. 使用PIL打开图片调整大小(保持宽高比),然后保存到一个临时文件(或者使用BytesIO内存流,避免写文件)。 2. 用openpyxl加载调整后的图片。 这里我们使用临时文件的方法(简单清晰): """ from PIL import Image as PILImage import openpyxl from openpyxl.drawing.image import Image as OpenpyxlImage import tempfile import os # 调整图片大小(保持宽高比)保存到临时文件 def resize_image_pil(img_path, max_width, max_height): pil_img = PILImage.open(img_path) # 计算新的尺寸,保持宽高比 original_width, original_height = pil_img.size ratio = min(max_width / original_width, max_height / original_height) new_size = (int(original_width * ratio), int(original_height * ratio)) resized_img = pil_img.resize(new_size, PILImage.ANTIALIAS) # 使用高质量下采样 # 创建临时文件 temp_file = tempfile.NamedTemporaryFile(suffix='.jpg', delete=False) resized_img.save(temp_file.name, format='JPEG') return temp_file.name # 使用示例 img_path = './0fc62dc1d223455794c475c70f041737躯干.jpg' max_width = 90 max_height = 90 temp_img_path = resize_image_pil(img_path, max_width, max_height) # 然后使用openpyxl加载这个临时图片 img = OpenpyxlImage(temp_img_path) # 插入Excel(同上) # ...(同方法一的插入代码) # 注意:插入后可以删除临时文件 os.unlink(temp_img_path) """ 但是,由于openpyxl的Image类不支持直接从PIL图像对象加载(需要文件路径或类似文件的对象),我们可以使用内存流(BytesIO)来避免写临时文件: """ from io import BytesIO # 调整图片大小(保持宽高比)保存到BytesIO对象 def resize_image_pil_to_bytes(img_path, max_width, max_height): pil_img = PILImage.open(img_path) original_width, original_height = pil_img.size ratio = min(max_width / original_width, max_height / original_height) new_size = (int(original_width * ratio), int(original_height * ratio)) resized_img = pil_img.resize(new_size, PILImage.ANTIALIAS) img_byte_arr = BytesIO() resized_img.save(img_byte_arr, format='JPEG') img_byte_arr.seek(0) # 将指针移回文件开头 return img_byte_arr # 使用示例 img_bytes = resize_image_pil_to_bytes(img_path, max_width, max_height) img = OpenpyxlImage(img_bytes) # openpyxl的Image类可以接受类似文件的对象 # 然后插入Excel # ...(同方法一的插入代码) """ 注意:使用内存流的方法不需要临时文件,更简洁。 综合两种方法,用户可以根据需要选择。如果对图片宽高比没有严格要求,方法一更简单;如果要求保持宽高比,则用方法二。 根据引用[3]中的示例,他们也是直接设置width和height,没有保持宽高比(因为每张图片的尺寸都是固定的114x101,这可能是不符合原图比例的)。所以用户可能不需要保持宽高比。 因此,我们提供方法一的完整代码,附上方法二的选项。 完整代码(方法一:不保持宽高比): """ import openpyxl from openpyxl.drawing.image import Image # 参数设置 excel_file = '我的数据.xlsx' # Excel文件名 sheet_name = "我的数据" # 工作表名 img_path = './0fc62dc1d223455794c475c70f041737躯干.jpg' # 图片路径 target_cell = 'D3' # 目标单元格 cell_width = 12.25 # 单元格宽度(字符单位) cell_height = 80.10 # 单元格高度(磅) img_width = 90 # 图片显示宽度(单位与Excel中一致) img_height = 90 # 图片显示高度 # 加载或创建工作簿 try: workbook = openpyxl.load_workbook(excel_file) except FileNotFoundError: workbook = openpyxl.Workbook() # 获取或创建工作表 if sheet_name in workbook.sheetnames: sheet = workbook[sheet_name] else: sheet = workbook.create_sheet(title=sheet_name, index=0) # 调整单元格尺寸(列宽和行高) column_letter = target_cell[0] # 从单元格地址中提取列字母 row_number = int(target_cell[1:]) # 提取行号 sheet.column_dimensions[column_letter].width = cell_width sheet.row_dimensions[row_number].height = cell_height # 加载图片设置尺寸 img = Image(img_path) img.width = img_width img.height = img_height # 插入图片 sheet.add_image(img, target_cell) # 保存 workbook.save(excel_file) print(f"图片插入到{sheet_name}工作表的{target_cell}单元格") """ 注意:单元格的列宽和行高设置不是必须的,但如果不设置,单元格可能太小而无法显示完整的图片。 如果用户需要保持宽高比,可以使用以下代码(方法二:使用内存流): """ import openpyxl from openpyxl.drawing.image import Image as OpenpyxlImage from PIL import Image as PILImage from io import BytesIO # 参数设置(同上) excel_file = '我的数据.xlsx' sheet_name = "我的数据" img_path = './0fc62dc1d223455794c475c70f041737躯干.jpg' target_cell = 'D3' cell_width = 12.25 cell_height = 80.10 max_width = 90 # 最大允许宽度 max_height = 90 # 最大允许高度 # 调整图片大小(保持宽高比)转换为BytesIO pil_img = PILImage.open(img_path) original_width, original_height = pil_img.size ratio = min(max_width / original_width, max_height / original_height) new_width = int(original_width * ratio) new_height = int(original_height * ratio) # 使用高质量重采样 resized_img = pil_img.resize((new_width, new_height), PILImage.ANTIALIAS) img_byte_arr = BytesIO() resized_img.save(img_byte_arr, format='JPEG') # 假设是JPEG格式,如果是其他格式需调整 img_byte_arr.seek(0) # 创建openpyxl的Image对象 img = OpenpyxlImage(img_byte_arr) # 注意:这里我们不需要设置img.width和img.height,因为图片已经调整到合适尺寸 # 但是,如果希望进一步控制,也可以设置(但可能没必要,因为已经调整了) # img.width = new_width # img.height = new_height # 加载或创建工作簿和工作表(同方法一) try: workbook = openpyxl.load_workbook(excel_file) except FileNotFoundError: workbook = openpyxl.Workbook() if sheet_name in workbook.sheetnames: sheet = workbook[sheet_name] else: sheet = workbook.create_sheet(title=sheet_name, index=0) # 调整单元格尺寸(可选,但推荐) column_letter = target_cell[0] row_number = int(target_cell[1:]) sheet.column_dimensions[column_letter].width = cell_width sheet.row_dimensions[row_number].height = cell_height # 插入图片 sheet.add_image(img, target_cell) workbook.save(excel_file) print(f"图片插入到{sheet_name}工作表的{target_cell}单元格,保持宽高比") """ 用户可以根据需求选择其中一种方法。 注意事项: 1. 使用PIL时,需要安装Pillow库:pip install Pillow 2. 图片路径要正确,否则会报错。 3. 插入图片后,保存工作簿时可能会覆盖原文件,请做好备份。 引用说明: 引用[1]和[3]提供了设置单元格尺寸和插入图片的示例,引用[2]提到使用openpyxl插入图片的方法[^1][^2][^3]。 相关问题: 1. 如何保持图片的宽高比? 2. 如何批量插入多张图片Excel的不同单元格? 3. 如何将Excel文件转换为PDF? 4. 插入图片后如何调整单元格大小以适应图片?</think>### Python 缩小图片尺寸插入Excel指定Sheet 以下是使用Python图片缩小嵌入Excel指定工作表的完整解决方案,结合引用[1][2][3]的最佳实践: #### 完整代码示例 ```python from openpyxl import load_workbook from openpyxl.drawing.image import Image from PIL import JpegImagePlugin # 修复PIL的兼容性问题 (引用[3]) JpegImagePlugin._getmp = lambda x: None def insert_image_to_excel(excel_path, sheet_name, img_path, target_cell, img_size=(100, 100)): """ 将图片插入Excel指定工作表 :param excel_path: Excel文件路径 :param sheet_name: 工作表名称 :param img_path: 图片路径 :param target_cell: 目标单元格(如'D3') :param img_size: 图片尺寸(宽, 高) """ # 加载工作簿和工作表 (引用[1][3]) wb = load_workbook(excel_path) ws = wb[sheet_name] # 设置单元格尺寸适应图片 (引用[1]) col_letter = target_cell[0] # 获取列字母 row_num = int(target_cell[1:]) # 获取行号 ws.column_dimensions[col_letter].width = img_size[0] / 7 # 列宽转换 ws.row_dimensions[row_num].height = img_size[1] * 0.75 # 行高转换 # 加载设置图片尺寸 (引用[1][2]) img = Image(img_path) img.width, img.height = img_size # 设置图片尺寸 # 插入图片到指定位置 (引用[2][3]) ws.add_image(img, target_cell) # 保存修改 wb.save(excel_path) print(f"图片插入{sheet_name}工作表的{target_cell}单元格") # 使用示例 insert_image_to_excel( excel_path="库存表.xlsx", sheet_name="产品图片", img_path="product_photo.jpg", target_cell="D3", img_size=(120, 90) # 自定义图片尺寸 ) ``` #### 关键步骤说明 1. **准备工作**: ```python pip install openpyxl pillow ``` 2. **图片尺寸设置**(引用[1][3]): ```python img = Image(img_path) img.width, img.height = (120, 90) # 设置显示尺寸 ``` 3. **单元格尺寸调整**(引用[1]): ```python # 设置列宽(单位:字符宽度) ws.column_dimensions['D'].width = 120 / 7 # ≈17.14 # 设置行高(单位:磅) ws.row_dimensions[3].height = 90 * 0.75 # =67.5 ``` 4. **图片插入**(引用[2][3]): ```python ws.add_image(img, 'D3') # 锚点定位 ``` #### 批量处理多张图片(引用[3]) ```python def batch_insert_images(excel_path, sheet_name, img_folder, start_cell='B3', img_size=(100, 100)): wb = load_workbook(excel_path) ws = wb[sheet_name] # 遍历图片文件夹 import os for i, filename in enumerate(os.listdir(img_folder)): if filename.lower().endswith(('.png', '.jpg', '.jpeg')): # 计算目标单元格 (B3, B4, B5...) target_cell = f"{start_cell[0]}{int(start_cell[1:]) + i}" # 插入图片 img_path = os.path.join(img_folder, filename) insert_image_to_excel(wb, ws, img_path, target_cell, img_size) wb.save(excel_path) # 使用示例 batch_insert_images( "产品目录.xlsx", "图库", "product_images/", img_size=(150, 150) ) ``` #### 注意事项 1. **尺寸比例**:单元格尺寸需与图片尺寸匹配,否则图片会被裁剪 2. **图片格式**:支持JPG/PNG等常见格式 3. **性能优化**:批量处理时建议: - 使用`wb = load_workbook(..., read_only=False)` - 处理完成后统一保存 4. **兼容性修复**(引用[3]): ```python from PIL import JpegImagePlugin JpegImagePlugin._getmp = lambda x: None ``` > 引用[1]展示了如何设置单元格尺寸适应图片[^1],引用[2]提供了图片插入的基本方法[^2],引用[3]演示了批量处理的最佳实践[^3]。
评论 12
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值