提取excel的指定列的值的后4位(数值),在其它列名的单元格中,批量嵌入与该数值匹配的图片(未实现居中),每间隔4行处理一次(合并过单元格)。
import pandas as pd
from openpyxl import load_workbook
from openpyxl.drawing.image import Image
from openpyxl.utils import get_column_letter
import os
# Excel文件路径
excel_file = r'E:\第二批400平台命名及台账信息_20250210_1.xlsx'
# 工作表名称
sheet_name = '电缆一班'
# 源数据列名(用于截取后四位的列)
source_column = '南网设备ID'
# 图片文件夹路径
image_folder = r'E:\现场图片'
# 每隔多少行处理一次
interval = 4
# 图片插入时相对于单元格边缘的偏移量(可根据需要调整)
offset_x = 5
offset_y = 1
# 读取Excel文件
df = pd.read_excel(excel_file, sheet_name=sheet_name)
# 加载Excel工作簿和工作表
wb = load_workbook(excel_file)
ws = wb[sheet_name]
# V/L-位置,W/M-编号
target_column_letter = 'V'
# 获取工作表的默认行高和列宽(用于调整图片大小)
default_row_height = ws.row_dimensions[1].height # 假设第一行的行高代表默认行高
default_col_width = ws.column_dimensions[target_column_letter].width # 获取目标列的默认列宽
# 由于openpyxl不支持直接获取图片的像素尺寸,我们需要假设一个图片尺寸或预先知道它
# 这里我们假设图片将被缩放到适合单元格的大小(可能需要根据实际情况调整)
image_width = default_col_width * 5 # 假设图片宽度是列宽的10倍(这个比例可能需要调整)
image_height = default_row_height * 4 # 假设图片高度是行高的8倍(这个比例也可能需要调整)
# 遍历DataFrame,每隔interval行处理一次
for i in range(0, len(df), interval):
# 获取当前行的数据
row_data = df.iloc[i]
# 截取源列值的后四位
code = str(row_data[source_column])[-4:]
# 构建图片文件名(假设图片文件名与截取的后四位代码匹配,扩展名为.jpg)
# V/L-位置,需要加'-1',W/M-编号无需
image_filename = f"{code}-1.jpg"
image_path = os.path.join(image_folder, image_filename)
# 检查图片是否存在
if os.path.exists(image_path):
# 计算图片插入的Excel行号(从1开始)
excel_row = i + 2 # DataFrame索引从0开始,Excel行号从1开始,且第一行是标题行,所以要加2
# 创建Image对象
img = Image(image_path)
# 设置图片大小
img.width = image_width
img.height = image_height
# 计算图片的锚点(由于我们要让图片看起来像是嵌入在单元格中,所以锚点需要稍微偏移以适应单元格边框)
# 注意:这里的偏移量可能需要根据你的Excel样式和图片大小进行调整
# openpyxl的anchor属性接受一个字符串,格式为'{列号}{行号}+{x偏移}+{y偏移}',但openpyxl不直接支持这种带偏移的anchor格式
# 因此,我们需要手动计算图片左上角的坐标,并使用add_image时指定top和left属性(但openpyxl的Image对象没有top和left属性,所以我们使用anchor的变通方法)
# 不过,为了简化,这里我们仅使用anchor的基本功能,并将图片放置在单元格的左上角附近
img.anchor = f'{target_column_letter}{excel_row}'
# 由于openpyxl的Image对象不直接支持设置top和left属性,我们需要通过调整anchor字符串中的行号和列号来模拟偏移
# 但这种方法并不精确,且依赖于单元格的大小和图片的缩放比例
# 一种更精确的方法是使用Lxml库直接操作XML,但这超出了本示例的范围
# 在这里,我们简单地将图片放置在单元格的左上角,并可能需要在Excel中手动调整图片位置以使其看起来像是嵌入的
# 为了模拟嵌入效果,我们可以将图片插入到前一个单元格的右侧(或根据需要调整)
# 但由于我们已经指定了目标列,这里我们直接插入到目标列
# 插入图片到工作表中
# 注意:由于anchor的限制和openpyxl的API,图片可能不会精确地放置在单元格内部
# 你可能需要在Excel中手动调整图片的大小和位置
ws.add_image(img)
else:
print(f"Image not found for code {code} in row {i + 2} (Excel row number).")
# 保存修改后的Excel文件(注意:由于图片是作为对象附加的,而不是真正嵌入到单元格中,所以保存后可能需要在Excel中手动调整)
wb.save(excel_file)
print('done!')