如何用openpyxl逐行提取Excel图片?现有方案存问题
从Excel提取PNG图片并按行存储的解决方案
我需要从Excel文件中提取PNG格式图片,尝试过多个Python脚本都未解决问题:
- 使用openpyxl的代码无任何输出
- 使用zipfile能提取图片,但无法按行单独存储
原openpyxl代码问题分析
原代码错误地认为图片存储在cell.value中,但实际上openpyxl里的图片是保存在工作表的_images属性里,而非单元格值中。需要通过图片的锚点(anchor)来确定它所属的行。
修正后的openpyxl实现(支持按行存储)
下面的代码会提取每张图片,并根据其所在行保存到对应命名的文件中,同时保留工作表和单元格信息:
from openpyxl import load_workbook import os def extract_images_by_row(excel_path, output_dir): os.makedirs(output_dir, exist_ok=True) wb = load_workbook(excel_path, data_only=True) for sheet_name in wb.sheetnames: sheet = wb[sheet_name] # 遍历工作表中的所有图片 for idx, img in enumerate(sheet._images): # 获取图片锚点对应的起始行(转成Excel实际行号) row_num = img.anchor._from.row + 1 # 构造保存路径,包含工作表名、行号和图片序号 save_path = os.path.join(output_dir, f"{sheet_name}_row_{row_num}_image_{idx+1}.png") # 保存图片 img.image.save(save_path) print(f"已保存图片: {save_path}") wb.close() # 示例调用 excel_file = r"C:/Users/A/Downloads/x/Me.xlsx" output_folder = r"C:/Users/A/Downloads/x/output_images" extract_images_by_row(excel_file, output_folder)
zipfile方法的改进(关联图片到行)
如果想用zipfile提取图片文件,再结合openpyxl获取图片位置信息来关联行,可以用以下方式:
import zipfile import os import shutil from openpyxl import load_workbook def extract_images_with_row_info(excel_path, output_dir): os.makedirs(output_dir, exist_ok=True) # 第一步:用zipfile提取所有PNG图片到临时目录 temp_media_dir = os.path.join(output_dir, "temp_media") with zipfile.ZipFile(excel_path, 'r') as zip_ref: for file in zip_ref.namelist(): if file.startswith("xl/media/") and file.endswith(".png"): zip_ref.extract(file, temp_media_dir) # 第二步:用openpyxl获取图片行信息,并重命名图片 wb = load_workbook(excel_path, data_only=True) for sheet_name in wb.sheetnames: sheet = wb[sheet_name] for idx, img in enumerate(sheet._images): row_num = img.anchor._from.row + 1 # 对应zip里的默认图片命名(image1.png、image2.png...) original_img_name = f"image{idx+1}.png" temp_img_path = os.path.join(temp_media_dir, "xl", "media", original_img_name) if os.path.exists(temp_img_path): new_img_name = f"{sheet_name}_row_{row_num}_{original_img_name}" final_path = os.path.join(output_dir, new_img_name) os.rename(temp_img_path, final_path) print(f"已整理图片: {final_path}") # 删除临时目录 shutil.rmtree(temp_media_dir) wb.close() # 示例调用 excel_file = r"C:/Users/AUC/Downloads/x/MedDigi-G.xlsx" output_folder = r"C:/Users/AUC/Downloads/x/output_images" extract_images_with_row_info(excel_file, output_folder)
关键说明
- 图片锚点
img.anchor._from.row是openpyxl内部的0起始行索引,加1可转换为Excel显示的行号 - zipfile提取的图片默认命名为
image1.png、image2.png,与openpyxl中sheet._images的遍历顺序完全对应
内容的提问来源于stack exchange,提问作者Omar Mokhtar
相关产品推荐
相关产品推荐

