openpyxl用SheetImageLoader读Excel图片报AbsoluteAnchor无_from属性错误如何解决
问题原因
Excel中的图片锚定方式分为三类,openpyxl-image-loader 库默认只兼容了 双单元格锚定(TwoCellAnchor) 类型的图片:
- 可正常处理的Excel文件内的图片都是双单元格锚定/单单元格锚定类型,锚点对象存在
_from属性 - 触发报错的Excel文件内存在使用 绝对锚定(AbsoluteAnchor) 类型的图片,这类锚点直接以页面坐标定位,没有绑定单元格,因此不存在
_from属性,库的原始代码没有做兼容判断就直接调用属性,就抛出了AttributeError。
修复方案
方案1:修改openpyxl-image-loader库源码实现兼容
找到安装路径下的sheet_image_loader.py文件(报错信息里的路径为/usr/local/lib/python3.8/site-packages/openpyxl_image_loader/sheet_image_loader.py),修改__init__方法中解析图片位置的逻辑,兼容三种锚点类型:
# 原代码第19行附近: # row = image.anchor._from.row + 1 # 替换为以下逻辑: from openpyxl.drawing.spreadsheet_drawing import TwoCellAnchor, OneCellAnchor, AbsoluteAnchor if isinstance(image.anchor, TwoCellAnchor): row = image.anchor._from.row + 1 col = image.anchor._from.col + 1 elif isinstance(image.anchor, OneCellAnchor): row = image.anchor._from.row + 1 col = image.anchor._from.col + 1 elif isinstance(image.anchor, AbsoluteAnchor): # 绝对锚定的图片没有绑定单元格,可根据业务需求处理 # 要么跳过这类图片,要么通过坐标换算对应单元格位置,以下为跳过逻辑 continue
如果需要处理绝对锚定的图片,可以通过image.anchor.pos.x和image.anchor.pos.y获取绝对坐标,再结合工作表的行高列宽换算出对应的单元格位置。
方案2:不修改库源码的临时修复
在自己的代码中重写SheetImageLoader的初始化逻辑,替换原来的库类使用即可:
from openpyxl_image_loader import SheetImageLoader from openpyxl.drawing.spreadsheet_drawing import TwoCellAnchor, OneCellAnchor, AbsoluteAnchor class CompatibleSheetImageLoader(SheetImageLoader): def __init__(self, sheet): self._sheet = sheet self._image_coordinates = {} for img in sheet._images: if isinstance(img.anchor, (TwoCellAnchor, OneCellAnchor)): row = img.anchor._from.row + 1 col = img.anchor._from.col + 1 if col not in self._image_coordinates: self._image_coordinates[col] = {} self._image_coordinates[col][row] = img # 绝对锚定的图片可在此处添加自定义处理逻辑
之后把原有代码中的image_loader = SheetImageLoader(sheet)替换为image_loader = CompatibleSheetImageLoader(sheet)即可正常运行。
内容的提问来源于stack exchange,提问作者Sajad Rezvani
相关产品推荐
相关产品推荐

