如何使用 Python 操作 Excel 图片:插入、提取与压缩

简介: 本文分享用Python高效处理Excel图片的实战技巧:批量插入500+产品图(xlwings精准对齐)、从Excel提取图片(openpyxl/Spire.XLS)、压缩图片减小文件体积(PIL),以及OCR识别图片表格转Excel。附完整代码与避坑指南,助你告别机械重复操作,1分钟搞定原需4小时的工作。(239字)


那天下午,我对着500张产品图发愁
事情是这样的。上个月公司要做一份产品目录,需要把500多款产品的图片插进Excel表格里,每个产品对应一行,图片放在第二列,大小还要统一。

我打开Excel,手动插了一张图——调整大小、拖到单元格里、对齐。看了一眼右下角的时间,我算了一笔账:一张图算30秒,500张就是250分钟,整整4个多小时。关键是这活儿毫无技术含量,纯属机械重复。
代理 IP 使用小技巧 让你的数据抓取效率翻倍 (33).png

那一刻我意识到,这事儿必须用Python解决。

后来我用几行代码搞定了这个任务,顺便还研究了怎么从Excel里提取图片、怎么压缩图片大小。今天就把这些经验整理出来,希望对你有用。

准备工作:先装好这些库
在动手之前,需要安装几个Python库。不同任务需要的库不太一样,但有几个是通用的:

基础图像处理

pip install pillow

操作Excel文件(选一个就行)

pip install openpyxl # 处理.xlsx文件,不支持图片插入
pip install xlwings # 需要本地有Excel软件
pip install spire.xls.free # 支持图片操作,无需Excel环境

需要说明的是,openpyxl这个库虽然很常用,但它对图片的操作能力非常有限——只能读取已有图片,无法插入或删除。如果你想要完整控制图片的增删改,推荐用spire.xls.free或者xlwings。

还有个更轻量的选择叫pywin32,它可以直接调用Windows上的Excel程序来干活,适合在Windows电脑上跑。

插入图片:把图片精准放到单元格里
回到开头那个问题:如何批量把图片插入Excel,并且精准对齐到每个单元格?

这里用一个叫xlwings的库来实现。它的原理是启动你电脑上的Excel程序,然后像人工操作一样往里填东西。

import xlwings as xw
import os

打开Excel文件

wb = xw.Book('产品目录.xlsx')
sheet = wb.sheets['产品列表']

图片存放的文件夹

image_folder = 'product_images/'

从第2行开始(假设第1行是表头)

for i, filename in enumerate(os.listdir(image_folder), start=2):
if filename.endswith(('.png', '.jpg')):

    # 构建图片完整路径
    img_path = os.path.join(image_folder, filename)

    # 把图片插入到B列当前行
    sheet.pictures.add(img_path, 
                      left=sheet.range(f'B{i}').left,
                      top=sheet.range(f'B{i}').top,
                      width=100,   # 设置宽度
                      height=80)   # 设置高度

    # 可选:调整行高让图片不重叠
    sheet.range(f'{i}:{i}').row_height = 80

wb.save()
wb.close()
print("搞定!图片已全部插入")

这段代码的核心逻辑很简单:遍历文件夹里的所有图片,把它们依次放到Excel的B列,从第2行开始往下排。left和top参数让图片的左上角对齐到单元格的左上角,这样位置就精准了。

如果你的需求更复杂,比如需要把图片放到特定的单元格(而不是按顺序),可以改成这样:

假设有一个字典,键是产品编号,值是对应图片路径

product_map = {
'A001': 'images/A001.jpg',
'A002': 'images/A002.jpg',

# ...

}

for product_id, img_path in product_map.items():

# 找到产品编号在哪一行
cell = sheet.range('A:A').find(product_id)
if cell:
    row = cell.row
    sheet.pictures.add(img_path,
                      left=sheet.range(f'C{row}').left,
                      top=sheet.range(f'C{row}').top,
                      width=100,
                      height=80)

这个逻辑是先找到产品编号所在的单元格位置,再把图片插到对应的C列。无论表格顺序怎么变,图片都不会放错。

提取图片:把Excel里的图片薅出来
有时候反过来,Excel文件里已经有一堆图片,需要把它们导出到文件夹里。这个场景常见于从别人发来的报表中提取素材。

openpyxl这个库虽然不能插入图片,但读取图片还是可以的。不过它只能处理.xlsx格式的文件,老版的.xls就不行了。

from openpyxl import load_workbook
from openpyxl_image_loader import SheetImageLoader
import os

加载Excel文件

wb = load_workbook('带图片的报告.xlsx')
sheet = wb.active

创建保存图片的文件夹

output_dir = 'extracted_images'
os.makedirs(output_dir, exist_ok=True)

用ImageLoader提取所有图片

image_loader = SheetImageLoader(sheet)

遍历所有单元格

for row in range(1, sheet.max_row + 1):
for col in range(1, sheet.max_column + 1):
cell = sheet.cell(row, col)
if image_loader.image_in(cell.coordinate):
img = image_loader.get(cell.coordinate)

        # 保存图片,用行列命名
        img.save(f'{output_dir}/img_{row}_{col}.png')
        print(f'已保存:第{row}行第{col}列的图片')

print(f'提取完成,图片保存在{output_dir}文件夹')

如果你用的是Spire.XLS库,提取图片的代码会更简洁:

from spire.xls import *

workbook = Workbook()
workbook.LoadFromFile('带图片的报告.xlsx')
sheet = workbook.Worksheets[0]

for i, picture in enumerate(sheet.Pictures):
picture.Picture.Save(f'extractedimages/pic{i}.png')

workbook.Dispose()

这里有个坑需要注意:如果Excel里的图片是“浮”在单元格上方的,而不是“嵌入”在单元格里的,上面的方法可能抓不到。这种情况下可以考虑用pywin32直接操作Excel程序来提取。

压缩图片:让臃肿的Excel文件瘦身
图片插多了,Excel文件会变得巨大。一个几兆的Excel,插了几十张高清图后可能变成几百兆,打开都费劲。

压缩图片的核心思路就是降低图片质量。用PIL(Pillow)库可以轻松做到:

from PIL import Image
import os

def compress_image(input_path, output_path, quality=50):
"""
压缩图片
quality: 1-100,数值越小压缩越狠,文件越小
"""
img = Image.open(input_path)

# 保存时指定quality,JPEG格式支持压缩
img.save(output_path, 'JPEG', quality=quality)

# 看看压缩效果
original_size = os.path.getsize(input_path) / 1024
compressed_size = os.path.getsize(output_path) / 1024
print(f'{os.path.basename(input_path)}: '
      f'{original_size:.1f}KB → {compressed_size:.1f}KB')

这个函数可以把一张几兆的图片压缩到几十KB,肉眼几乎看不出差别。quality参数是关键,设为50左右能兼顾文件大小和清晰度。

如果有多张图片需要批量压缩,可以这样:

def batch_compress(folder_path, quality=50):
for filename in os.listdir(folder_path):
if filename.endswith(('.png', '.jpg', '.jpeg')):
input_path = os.path.join(folder_path, filename)
output_path = os.path.join(folderpath, f'compressed{filename}')
compress_image(input_path, output_path, quality)

还有个更高级的玩法:多阶段压缩。如果一次压缩达不到目标大小,就逐步降低质量,甚至缩小尺寸,直到文件够小为止。

def compress_to_target(img_path, target_kb=100, max_attempts=5):
"""反复压缩直到文件小于target_kb"""
quality = 80
for attempt in range(max_attempts):
temppath = f'temp{attempt}.jpg'
compress_image(img_path, temp_path, quality)

    if os.path.getsize(temp_path) / 1024 <= target_kb:
        # 压缩成功
        os.replace(temp_path, img_path)
        return True

    # 还不够小,继续降低质量
    quality -= 15
    os.remove(temp_path)

return False

如果你用的是Spire.XLS库,它自带了图片压缩方法,可以直接在Excel内部压缩,不需要先导出再插回:

from spire.xls import *

workbook = Workbook()
workbook.LoadFromFile('需要压缩图片的表格.xlsx')

for sheet in workbook.Worksheets:
for picture in sheet.Pictures:

    # 直接压缩图片,参数是压缩比例
    picture.Compress(50)

workbook.SaveToFile('压缩后的表格.xlsx', ExcelVersion.Version2016)
workbook.Dispose()

这种方式的好处是操作简单,而且压缩后的图片还待在原来的位置,不用重新排版。

进阶:从图片表格里提取文字到Excel
还有一种情况很常见:你手里有一张图片格式的表格(比如扫描件、截图),想把它转成可编辑的Excel。

这就用到OCR技术了。Tesseract是一个开源的OCR引擎,配合Python的pytesseract库可以搞定:

import pytesseract
from PIL import Image
import pandas as pd

如果Tesseract没在系统路径里,需要指定一下

pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'

def image_to_excel(img_path, output_excel):

# 读取图片
img = Image.open(img_path)

# 识别文字,chi_sim是中文简体模型
text = pytesseract.image_to_string(img, lang='chi_sim+eng')

# 把识别结果按行分割
lines = text.strip().split('\n')

# 转换成DataFrame并保存
df = pd.DataFrame([line.split('\t') for line in lines])
df.to_excel(output_excel, index=False, header=False)

print(f'识别完成,结果保存在{output_excel}')

使用示例

image_to_excel('表格截图.png', '识别结果.xlsx')

这种方法的识别精度取决于图片质量。如果图片不够清晰,可以先用PIL做一下预处理:

def preprocess_image(img_path):
img = Image.open(img_path)

# 转为灰度图
img = img.convert('L')
# 提高对比度
from PIL import ImageEnhance
enhancer = ImageEnhance.Contrast(img)
img = enhancer.enhance(2.0)
return img

如果你想达到更高的识别准确率(比如98%以上),可以考虑用商业OCR接口,比如百度OCR。它专门优化过表格识别场景,还能自动解析表格的行列结构。不过这是付费服务,有免费额度,适合企业级应用。

避坑指南:这些细节不注意会翻车
路径问题
Windows路径里的反斜杠\需要转义,或者直接用正斜杠/。保险的做法是:

img_path = r'C:\Users\name\images\product.jpg'

或者

img_path = 'C:/Users/name/images/product.jpg'

Excel被占用
如果你的代码运行时报错说文件被占用,记得先把Excel关掉。xlwings这类库启动Excel程序时,如果文件已经打开可能会冲突。

图片格式兼容
.png支持透明背景,.jpg压缩率高但不支持透明。插入到Excel里两种都能用,但压缩时要注意:PNG转JPEG会丢失透明通道。

VBA权限问题
如果用pywin32的方式插入图片,需要提前在Excel里开启“信任对VBA项目对象模型的访问”权限。具体路径:Excel选项 → 信任中心 → 信任中心设置 → 宏设置 → 勾选这个选项。这步不做会报错。

内存溢出
批量处理大量图片时,如果电脑内存不够用,可以考虑分批处理。比如一次处理100张,处理完释放内存再继续。

收个尾
回头来看,那天下午让我发愁的500张产品图,最后用Python不到一分钟就跑完了。代码跑起来的那一刻,看着屏幕上的进度条噌噌往前走,那种感觉确实挺爽的。

Excel和图片打交道这件事,用Python来搞无非就是三个核心操作:插进去、薅出来、压一压。掌握了这几个套路,以后再遇到类似的活儿,就不用跟Excel较劲了。

希望这篇文章能帮你省下几个小时的摸鱼时间。代码都在上面了,复制粘贴改改路径就能用。如果有问题,欢迎交流讨论。

目录
相关文章
|
9天前
|
人工智能 JSON 机器人
让龙虾成为你的“公众号分身” | 阿里云服务器玩Openclaw
本文带你零成本玩转OpenClaw:学生认证白嫖6个月阿里云服务器,手把手配置飞书机器人、接入免费/高性价比AI模型(NVIDIA/通义),并打造微信公众号“全自动分身”——实时抓热榜、AI选题拆解、一键发布草稿,5分钟完成热点→文章全流程!
11146 102
让龙虾成为你的“公众号分身” | 阿里云服务器玩Openclaw
|
9天前
|
人工智能 IDE API
2026年国内 Codex 安装教程和使用教程:GPT-5.4 完整指南
Codex已进化为AI编程智能体,不仅能补全代码,更能理解项目、自动重构、执行任务。本文详解国内安装、GPT-5.4接入、cc-switch中转配置及实战开发流程,助你从零掌握“描述需求→AI实现”的新一代工程范式。(239字)
5568 135
|
7天前
|
人工智能 并行计算 Linux
本地私有化AI助手搭建指南:Ollama+Qwen3.5-27B+OpenClaw阿里云/本地部署流程
本文提供的全流程方案,从Ollama安装、Qwen3.5-27B部署,到OpenClaw全平台安装与模型对接,再到RTX 4090专属优化,覆盖了搭建过程的每一个关键环节,所有代码命令可直接复制执行。使用过程中,建议优先使用本地模型保障隐私,按需切换云端模型补充功能,同时注重显卡温度与显存占用监控,确保系统稳定运行。
1925 5
|
6天前
|
人工智能 自然语言处理 供应链
【最新】阿里云ClawHub Skill扫描:3万个AI Agent技能中的安全度量
阿里云扫描3万+AI Skill,发现AI检测引擎可识别80%+威胁,远高于传统引擎。
1394 3
|
6天前
|
人工智能 Linux API
离线AI部署终极手册:OpenClaw+Ollama本地模型匹配、全环境搭建与问题一站式解决
在本地私有化部署AI智能体,已成为隐私敏感、低成本、稳定运行的主流方案。OpenClaw作为轻量化可扩展Agent框架,搭配Ollama本地大模型运行工具,可实现完全离线、无API依赖、无流量费用的个人数字助理。但很多用户在实践中面临三大难题:**不知道自己硬件能跑什么模型、显存/内存频繁爆仓、Skills功能因模型不支持工具调用而失效**。
3114 7