URLhttps://learnscript.net/zh/office-programming/openpyxl/images/
    复制链接转到说明  示例

    如何使用 openpyxl 处理 Excel 图像?Image 对象介绍

    我被代码海扁署名-非商业-禁演绎
    阅读 9:43·字数 2915·更新 

    openpyxl Excel 图像对象 Image

    openpyxl包的Image类,属于模块openpyxl.drawing.image,表示 Microsoft Excel 工作表中的图像。Image对象一般存储在 Excel 工作表对象中,而不是单元格对象,虽然图像可以将锚点设置到某一个单元格。

    Image 类依赖于 pillow 包

    要让Image类正常工作,需要安装包pillow,否则,openpyxl将无法读取工作表中的图像,也无法添加图像至工作表。

    创建 Excel 图像

    如果你希望为 Excel 工作表添加图像,那么需要首先创建Image对象,然后通过工作表对象的相关方法执行添加操作。

    Image(img)

    img 参数

    img参数一般是一个表示图像文件路径的字符串,或一个实现了抽象基类os.PathLike的对象。

    create.py
    from openpyxl.drawing.image import Image
    
    # 创建一个 Image 对象 print(Image('python.png'))
    <openpyxl.drawing.image.Image object at >

    为 Excel 工作表添加图像

    WorksheetWriteOnlyWorksheet对象的add_image方法,可用于为 Excel 工作表添加图像,当然,这需要一个有效的Image对象。

    worksheet|writeonlyworksheet.add_image(img, anchor=None)

    img 参数

    img参数是一个Image对象,其对应的图像将被添加至工作表。

    anchor 参数

    anchor参数是一个表示单元格地址的字符串,相关的单元格将作为被添加图像的锚点(图像将被定位至单元格的左上角)。

    在下面的示例中,我们将图像添加至工作表Images,并设置其锚点为单元格B2

    add.py
    # 创建只写工作簿,并添加工作表 Images
    from openpyxl import Workbook
    wb = Workbook(True)
    ws = wb.create_sheet('Images')
    
    from openpyxl.drawing.image import Image
    # 将图像 python.png 添加至工作表,锚点为 B2 img = Image('python.png') ws.add_image(img, 'B2')
    wb.save('Add.xlsx')

    将同一个 Image 对象重复添加至同一个工作表对象可能会导致警告

    如果一个Image对象已经存在于某个工作表对象中,那么再次将其添加至该工作表可能会产生警告,但这些警告不会影响图像的添加。

    如果你为同一个图像文件创建多个Image对象,那么将这些Image对象添加至某个工作表不会导致警告的出现,但可能导致保存后的文件过大,因为每个图像都会被存储,即使他们是一样的。

    在下面的示例中,我们反复将Image对象添加到工作表Images,这导致了警告的产生。

    add_again.py
    # 创建只写工作簿,并添加工作表 Images
    from openpyxl import Workbook
    wb = Workbook(True)
    ws = wb.create_sheet('Images')
    
    from openpyxl.drawing.image import Image
    # 创建一个 Image 对象,并添加至 Images img = Image('python.png') ws.add_image(img, 'A1') # 重复添加会产生警告,但不影响添加 ws.add_image(img, 'B2') ws.add_image(img, 'C3')
    wb.save('Again.xlsx')
    zipfile\__init__.py:: UserWarning: Duplicate name: 'xl/media/image3.png'

    不要将同一个 Image 对象添加至不同的工作表对象

    如果将同一个Image对象添加到不同的工作表对象中,那么该Image对象所对应的图像仅能在一个工作表中正常显示,其他工作表将无法加载该Image对象对应的图像。

    并且,在保存 Excel 文件之后,再次以非只读方式读取保存的 Excel 文件,可能会导致异常KeyError: "There is no item named 'xl/media/…' in the archive"

    在下面的示例中,我们首先将Image对象添加至工作表Images1,然后又将其添加至工作表Images2,这会导致工作表Images1中的图像无法正常加载。

    add_diff.py
    # 创建只写工作簿,并添加工作表 Images1,Images2
    from openpyxl import Workbook
    wb = Workbook(True)
    ws1 = wb.create_sheet('Images1')
    ws2 = wb.create_sheet('Images2')
    
    from openpyxl.drawing.image import Image
    # 创建一个 Image 对象,并添加至 Images1 img = Image('python.png') ws1.add_image(img, 'A1') # 将 Image 对象添加至 Images2 ws2.add_image(img, 'B2')
    wb.save('Diff.xlsx')
    from openpyxl import load_workbook # ERROR 不能以非只读方式读取 Diff.xlsx wb = load_workbook('Diff.xlsx')
    zipfile\__init__.py:: UserWarning: Duplicate name: 'xl/media/image2.png'

    KeyError: "There is no item named 'xl/media/image1.png' in the archive"

    获取,替换,删除 Excel 工作表中的图像

    openpyxl包的设计者似乎不希望开发人员可以获取或设置 Excel 工作表中的图像,因此,WorksheetWriteOnlyWorksheet对象拥有一个以_开头的变量_images,该变量是一个包含Image对象的 Python 列表,每一个Image对象对应工作表中的一个图像。

    事实上,为WorksheetWriteOnlyWorksheet对象的_images列表添加Image对象,或者替换或删除_images列表中的Image对象,等同于为工作表添加图像,或者替换或删除工作表中的图像。当然,你可以将一个新的 Python 列表直接赋值给WorksheetWriteOnlyWorksheet对象的_images变量,这将替换工作表中的所有图像。

    worksheet|writeonlyworksheet._images
    worksheet|writeonlyworksheet._images = images

    images 值

    images是一个 Python 列表,列表中的元素应该是Image对象。

    在下面的示例中,我们通过Worksheet对象的_images列表,对工作表中的图像进行了替换,删除和添加。

    images.py
    # 读取 Excel 文件 Img.xlsx 中的工作表 Images
    from openpyxl import load_workbook
    wb = load_workbook('Img.xlsx')
    ws = wb['Images']
    
    from openpyxl.drawing.image import Image
    # 获取 Excel 工作表中的图像 print(f'一共 {len(ws._images)} 个图像')
    # 替换第一个图像 ws._images[0] = Image('imac-icon.png') # 删除第二个图像 del ws._images[1] # 添加一个图像 ws._images.append(Image('python.png'))
    wb.save('NewImg.xlsx')
    一共 2 个图像

    获取和设置 Excel 图像的锚点

    Image对象的anchor变量,表示Image对象对应的 Excel 图像的锚点,该变量可能是一个字符串,表示作为锚点的单元格的地址,也可能是openpyxl包的TwoCellAnchor对象,表示图像的显示区域。当你希望设置图像在工作表中的锚点时,可将表示单元格地址的字符串赋值给Image对象的anchor变量。

    image.anchor
    image.anchor = anchor

    anchor 值

    anchor可以是表示单元格地址的字符串。

    TwoCellAnchor 对象

    上述TwoCellAnchor对象,可被Image对象用于表示图像的显示区域。TwoCellAnchor对象的_from特性的colrow变量,是图像锚点所对应的单元格的列索引和行索引,0表示第一列或第一行。

    anchor.py
    # 读取 Excel 文件 Img.xlsx 中的工作表 Images
    from openpyxl import load_workbook
    wb = load_workbook('Img.xlsx')
    ws = wb['Images']
    
    for i in ws._images: # 获取 Excel 工作表中的图像的锚点 a = i.anchor print(type(a)) print(f'锚点:{a._from.col}{a._from.row}')
    # 设置新的锚点 i.anchor = 'E5'
    wb.save('Anchor.xlsx')
    <class 'openpyxl.drawing.spreadsheet_drawing.TwoCellAnchor'>
    锚点:0,0
    <class 'openpyxl.drawing.spreadsheet_drawing.TwoCellAnchor'>
    锚点:2,1

    获取 Excel 图像的原始大小

    Image对象的widthheight变量,表示Image对象对应的 Excel 图像的原始宽度和高度,这可能与图像在工作表中的实际显示大小不同。

    image.width
    image.height

    在 Excel 文件Img.xlsx中,工作表Images包含两个显示大小不同的图像,但其原始大小一致。

    size.py
    # 读取 Excel 文件 Img.xlsx 中的工作表 Images
    from openpyxl import load_workbook
    wb = load_workbook('Img.xlsx')
    ws = wb['Images']
    
    # 获取 Excel 工作表中的图像的原始大小 for i in ws._images: print(f'原始大小:{i.width}x{i.height}')
    原始大小:128x128
    原始大小:128x128

    获取 Excel 图像的格式

    Image对象的format变量是一个字符串,表示Image对象对应的 Excel 图像的格式,如果无法得知图像的格式,那么format变量保持其默认值png

    image.format

    在 Excel 文件Img.xlsx中,工作表Chat包含两个图像,他们的格式分别为pngsvg,但格式为svg的图像被识别为png格式。

    format.py
    # 读取 Excel 文件 Img.xlsx 中的工作表 Chat
    from openpyxl import load_workbook
    wb = load_workbook('Img.xlsx')
    ws = wb['Chat']
    
    # 获取 Excel 工作表中的图像的格式 for i in ws._images: print(f'格式:{i.format}')
    格式:png
    格式:png

    Image 对象的其他特性

    以下是Image对象的其他相关特性。

    ref 变量

    Image对象的ref变量表示图像的来源,他可能是表示图像文件路径的字符串,也可能是包含图像数据的对象,比如一个_io.BytesIO对象。

    源码

    src/zh/openpyxl/images·codebeatme/office-programming·GitHub