You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用openpyxl导入.bin图片至Excel时遇KeyError: '.wmf'求助

解决openpyxl插入.bin(WMF矢量图)时的KeyError: '.wmf'问题

问题原因

你提取的.bin文件本质是WMF矢量格式,openpyxl识别出图片类型为WMF后,会尝试从系统MIME类型映射中查找.wmf对应的类型,但你的Python环境未注册该MIME类型,因此抛出KeyError。

解决方法

方法1:手动注册WMF的MIME类型

在脚本开头添加代码,将WMF的MIME类型注册到mimetypes库,让openpyxl能找到对应映射:

import mimetypes
mimetypes.add_type('image/x-wmf', '.wmf')

方法2:保留真实格式扩展名(推荐)

Excel中的.bin图片实际是WMF格式,重命名提取的文件时改为.wmf扩展名(比如image1.bin→image1.wmf),openpyxl可直接识别格式并匹配MIME类型,无需额外注册。

方法3:改用xlsxwriter插入图片

xlsxwriter对矢量图支持更友好,原生兼容WMF格式,无需额外处理MIME类型。

修正后的完整代码

结合方法1的修正版本,同时修复原代码中的路径错误、文件名重复、频繁保存等问题:

from zipfile import ZipFile
from pathlib import Path
import sys
import os
import openpyxl
from openpyxl.drawing.image import Image
import mimetypes

# 注册WMF的MIME类型,解决KeyError
mimetypes.add_type('image/x-wmf', '.wmf')

# 识别图片文件
imgformats = ('bin',)  # 元组正确写法,避免被解析为字符串
def is_image(filename):
    return any(filename.endswith(ext) for ext in imgformats)

# 创建保存目录
folders = ['imgsave']
for folder in folders:
    if not os.path.exists(folder):
        os.makedirs(folder)

# 获取所有xlsx文件
path = Path(".")
try:
    files = list(path.glob('*.xlsx'))  # 转为列表避免迭代失效
except PermissionError as e:
    print(f'Permission Error: {str(e)}')
    sys.exit()

# 统计变量初始化
file_count = 0
overall_size = 0
data = []

# 提取图片到指定目录
media_dir = Path('xl/media')
media_dir.mkdir(parents=True, exist_ok=True)  # 确保目录层级存在

for file in files:
    with ZipFile(file) as working_zip:
        image_list = [name for name in working_zip.namelist() if is_image(name)]
        # 统计文件大小和数量
        for img in image_list:
            overall_size += working_zip.getinfo(img).file_size
        file_count = len(image_list)
        # 提取图片文件
        working_zip.extractall("", image_list)
        # 重命名并移动到media目录,避免文件名重复
        for idx, img in enumerate(image_list):
            new_name = media_dir / f'{file.stem}_{idx+1}.bin'
            os.rename(img, new_name)
        data.append(file_count)
        data.append(overall_size)

# 生成图片插入的单元格位置
cellcycletemp = ['A', 'H', 'O', 'V', 'AC']
col_count = len(cellcycletemp)
cellcycle = [cellcycletemp[n%col_count] + str((n//col_count) +13) for n in range(120)]

# 创建新Excel并插入图片
wb = openpyxl.Workbook()
ws = wb.worksheets[0]

# 获取所有提取的.bin图片
imagelist = [f for f in os.listdir(media_dir) if f.endswith('.bin')]
# 插入图片(限制数量不超过预生成的单元格位置)
for n, file in enumerate(imagelist[:120]):
    img_path = media_dir / file
    img = Image(img_path)
    img.anchor = cellcycle[n]
    ws.add_image(img)

# 统一保存文件,避免重复IO操作
wb.save('imgsave/combined images.xlsx')

额外说明

  • 若选择方法2,只需将重命名逻辑中的.bin改为.wmf,可省略MIME类型注册步骤。
  • 原代码中rows=4与cellcycletemp的5个元素不匹配,已修正为按列数自动计算单元格位置。
  • 避免在循环内多次调用wb.save(),所有图片插入完成后统一保存可提升运行效率。

内容的提问来源于stack exchange,提问作者Tea

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 14:30:48