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

如何用Openpyxl在XLSX多工作表添加同一张图片且不增大文件体积?

解决Openpyxl重复插入同一张图片不产生副本的问题

核心思路:复用图片的二进制资源

Openpyxl默认每次添加图片都会重新读取文件并存储副本,但我们可以通过预加载图片的二进制数据,让多个工作表共享同一份图片资源,既规避文件关闭报错,又避免Excel重复存储图片导致体积臃肿。

具体实现步骤

  • 一次性读取图片二进制内容:先打开图片文件读取字节数据,之后关闭文件,避免后续重复操作引发I/O错误。
  • 创建基础图片对象:基于读取到的字节数据生成一个基础Image对象,用于复用其image_data属性。
  • 在多工作表中复用资源:每个工作表创建新的Image对象,但直接复用基础对象的image_data,让Excel识别为同一份嵌入资源。

示例代码

from openpyxl import Workbook
from openpyxl.drawing.image import Image

# 仅读取一次图片二进制数据
with open("product.jpg", "rb") as img_file:
    img_raw_data = img_file.read()

wb = Workbook()

# 创建基础图片对象,用于提供共享的image_data
base_image = Image()
base_image.image_data = img_raw_data

# 给多个工作表添加同一张图片
for sheet_title in ["产品列表1", "产品列表2", "产品列表3"]:
    ws = wb.create_sheet(title=sheet_title)
    # 新建图片对象但复用基础资源
    target_img = Image()
    target_img.image_data = base_image.image_data
    target_img.anchor = "B2"  # 设置图片在工作表中的位置
    ws.add_image(target_img)

# 删除默认生成的空白工作表
wb.remove(wb["Sheet"])

wb.save("产品报表.xlsx")

原理说明

Openpyxl的Image对象通过image_data存储图片的二进制内容,当多个Image对象共享同一image_data时,Excel会将该图片作为单一嵌入资源保存,所有工作表的图片引用都会指向这份资源,不会重复存储。同时预读取字节数据的方式,彻底避免了重复打开文件引发的ValueError: I/O operation on closed file错误。

额外提示

  • 如果需要调整不同工作表中图片的大小、样式,直接在对应工作表的target_img对象上设置即可,不会影响共享的图片资源。
  • 该方法支持JPG、PNG等Openpyxl兼容的所有图片格式,效果和手动复制图片完全一致,文件体积不会因重复引用增大。

内容的提问来源于stack exchange,提问作者A. Sudnikovich

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 16:13:12