使用Python實現(xiàn)Excel圖片插入、提取與壓縮操作
?事情是這樣的。上個月公司要做一份產(chǎn)品目錄,需要把500多款產(chǎn)品的圖片插進Excel表格里,每個產(chǎn)品對應(yīng)一行,圖片放在第二列,大小還要統(tǒng)一。
我打開Excel,手動插了一張圖——調(diào)整大小、拖到單元格里、對齊??戳艘谎塾蚁陆堑臅r間,我算了一筆賬:一張圖算30秒,500張就是250分鐘,整整4個多小時。關(guān)鍵是這活兒毫無技術(shù)含量,純屬機械重復(fù)。
那一刻我意識到,這事兒必須用Python解決。
后來我用幾行代碼搞定了這個任務(wù),順便還研究了怎么從Excel里提取圖片、怎么壓縮圖片大小。今天就把這些經(jīng)驗整理出來,希望對你有用。
準備工作:先裝好這些庫
在動手之前,需要安裝幾個Python庫。不同任務(wù)需要的庫不太一樣,但有幾個是通用的:
# 基礎(chǔ)圖像處理 pip install pillow # 操作Excel文件(選一個就行) pip install openpyxl # 處理.xlsx文件,不支持圖片插入 pip install xlwings # 需要本地有Excel軟件 pip install spire.xls.free # 支持圖片操作,無需Excel環(huán)境
需要說明的是,openpyxl這個庫雖然很常用,但它對圖片的操作能力非常有限——只能讀取已有圖片,無法插入或刪除。如果你想要完整控制圖片的增刪改,推薦用spire.xls.free或者xlwings。
還有個更輕量的選擇叫pywin32,它可以直接調(diào)用Windows上的Excel程序來干活,適合在Windows電腦上跑。
插入圖片:把圖片精準放到單元格里
回到開頭那個問題:如何批量把圖片插入Excel,并且精準對齊到每個單元格?
這里用一個叫xlwings的庫來實現(xiàn)。它的原理是啟動你電腦上的Excel程序,然后像人工操作一樣往里填東西。
import xlwings as xw
import os
# 打開Excel文件
wb = xw.Book('產(chǎn)品目錄.xlsx')
sheet = wb.sheets['產(chǎn)品列表']
# 圖片存放的文件夾
image_folder = 'product_images/'
# 從第2行開始(假設(shè)第1行是表頭)
for i, filename in enumerate(os.listdir(image_folder), start=2):
if filename.endswith(('.png', '.jpg')):
# 構(gòu)建圖片完整路徑
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, # 設(shè)置寬度
height=80) # 設(shè)置高度
# 可選:調(diào)整行高讓圖片不重疊
sheet.range(f'{i}:{i}').row_height = 80
wb.save()
wb.close()
print("搞定!圖片已全部插入")
這段代碼的核心邏輯很簡單:遍歷文件夾里的所有圖片,把它們依次放到Excel的B列,從第2行開始往下排。left和top參數(shù)讓圖片的左上角對齊到單元格的左上角,這樣位置就精準了。
如果你的需求更復(fù)雜,比如需要把圖片放到特定的單元格(而不是按順序),可以改成這樣:
# 假設(shè)有一個字典,鍵是產(chǎn)品編號,值是對應(yīng)圖片路徑
product_map = {
'A001': 'images/A001.jpg',
'A002': 'images/A002.jpg',
# ...
}
for product_id, img_path in product_map.items():
# 找到產(chǎn)品編號在哪一行
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)
這個邏輯是先找到產(chǎn)品編號所在的單元格位置,再把圖片插到對應(yīng)的C列。無論表格順序怎么變,圖片都不會放錯。
提取圖片:把Excel里的圖片薅出來
有時候反過來,Excel文件里已經(jīng)有一堆圖片,需要把它們導(dǎo)出到文件夾里。這個場景常見于從別人發(fā)來的報表中提取素材。
openpyxl這個庫雖然不能插入圖片,但讀取圖片還是可以的。不過它只能處理.xlsx格式的文件,老版的.xls就不行了。
from openpyxl import load_workbook
from openpyxl_image_loader import SheetImageLoader
import os
# 加載Excel文件
wb = load_workbook('帶圖片的報告.xlsx')
sheet = wb.active
# 創(chuàng)建保存圖片的文件夾
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'extracted_images/pic_{i}.png')
workbook.Dispose()
這里有個坑需要注意:如果Excel里的圖片是“浮”在單元格上方的,而不是“嵌入”在單元格里的,上面的方法可能抓不到。這種情況下可以考慮用pywin32直接操作Excel程序來提取。
壓縮圖片:讓臃腫的Excel文件瘦身
圖片插多了,Excel文件會變得巨大。一個幾兆的Excel,插了幾十張高清圖后可能變成幾百兆,打開都費勁。
壓縮圖片的核心思路就是降低圖片質(zhì)量。用PIL(Pillow)庫可以輕松做到:
from PIL import Image
import os
def compress_image(input_path, output_path, quality=50):
"""
壓縮圖片
quality: 1-100,數(shù)值越小壓縮越狠,文件越小
"""
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')
這個函數(shù)可以把一張幾兆的圖片壓縮到幾十KB,肉眼幾乎看不出差別。quality參數(shù)是關(guān)鍵,設(shè)為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(folder_path, f'compressed_{filename}')
compress_image(input_path, output_path, quality)
還有個更高級的玩法:多階段壓縮。如果一次壓縮達不到目標大小,就逐步降低質(zhì)量,甚至縮小尺寸,直到文件夠小為止。
def compress_to_target(img_path, target_kb=100, max_attempts=5):
"""反復(fù)壓縮直到文件小于target_kb"""
quality = 80
for attempt in range(max_attempts):
temp_path = 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
# 還不夠小,繼續(xù)降低質(zhì)量
quality -= 15
os.remove(temp_path)
return False
如果你用的是Spire.XLS庫,它自帶了圖片壓縮方法,可以直接在Excel內(nèi)部壓縮,不需要先導(dǎo)出再插回:
from spire.xls import *
workbook = Workbook()
workbook.LoadFromFile('需要壓縮圖片的表格.xlsx')
for sheet in workbook.Worksheets:
for picture in sheet.Pictures:
# 直接壓縮圖片,參數(shù)是壓縮比例
picture.Compress(50)
workbook.SaveToFile('壓縮后的表格.xlsx', ExcelVersion.Version2016)
workbook.Dispose()
這種方式的好處是操作簡單,而且壓縮后的圖片還待在原來的位置,不用重新排版。
進階:從圖片表格里提取文字到Excel
還有一種情況很常見:你手里有一張圖片格式的表格(比如掃描件、截圖),想把它轉(zhuǎn)成可編輯的Excel。
這就用到OCR技術(shù)了。Tesseract是一個開源的OCR引擎,配合Python的pytesseract庫可以搞定:
import pytesseract
from PIL import Image
import pandas as pd
# 如果Tesseract沒在系統(tǒng)路徑里,需要指定一下
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')
# 把識別結(jié)果按行分割
lines = text.strip().split('\n')
# 轉(zhuǎn)換成DataFrame并保存
df = pd.DataFrame([line.split('\t') for line in lines])
df.to_excel(output_excel, index=False, header=False)
print(f'識別完成,結(jié)果保存在{output_excel}')
# 使用示例
image_to_excel('表格截圖.png', '識別結(jié)果.xlsx')
這種方法的識別精度取決于圖片質(zhì)量。如果圖片不夠清晰,可以先用PIL做一下預(yù)處理:
def preprocess_image(img_path):
img = Image.open(img_path)
# 轉(zhuǎn)為灰度圖
img = img.convert('L')
# 提高對比度
from PIL import ImageEnhance
enhancer = ImageEnhance.Contrast(img)
img = enhancer.enhance(2.0)
return img
如果你想達到更高的識別準確率(比如98%以上),可以考慮用商業(yè)OCR接口,比如百度OCR。它專門優(yōu)化過表格識別場景,還能自動解析表格的行列結(jié)構(gòu)。不過這是付費服務(wù),有免費額度,適合企業(yè)級應(yīng)用。
避坑指南:這些細節(jié)不注意會翻車
路徑問題
Windows路徑里的反斜杠``需要轉(zhuǎn)義,或者直接用正斜杠/。保險的做法是:
img_path = r'C:\Users\name\images\product.jpg' # 或者 img_path = 'C:/Users/name/images/product.jpg'
Excel被占用
如果你的代碼運行時報錯說文件被占用,記得先把Excel關(guān)掉。xlwings這類庫啟動Excel程序時,如果文件已經(jīng)打開可能會沖突。
圖片格式兼容
.png支持透明背景,.jpg壓縮率高但不支持透明。插入到Excel里兩種都能用,但壓縮時要注意:PNG轉(zhuǎn)JPEG會丟失透明通道。
VBA權(quán)限問題
如果用pywin32的方式插入圖片,需要提前在Excel里開啟“信任對VBA項目對象模型的訪問”權(quán)限。具體路徑:Excel選項 → 信任中心 → 信任中心設(shè)置 → 宏設(shè)置 → 勾選這個選項。這步不做會報錯。
內(nèi)存溢出
批量處理大量圖片時,如果電腦內(nèi)存不夠用,可以考慮分批處理。比如一次處理100張,處理完釋放內(nèi)存再繼續(xù)。
收個尾
回頭來看,那天下午讓我發(fā)愁的500張產(chǎn)品圖,最后用Python不到一分鐘就跑完了。代碼跑起來的那一刻,看著屏幕上的進度條噌噌往前走,那種感覺確實挺爽的。
Excel和圖片打交道這件事,用Python來搞無非就是三個核心操作:插進去、薅出來、壓一壓。掌握了這幾個套路,以后再遇到類似的活兒,就不用跟Excel較勁了。
到此這篇關(guān)于使用Python實現(xiàn)Excel圖片插入、提取與壓縮操作的文章就介紹到這了,更多相關(guān)Python操作Excel圖片內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Python中Excel圖片插入、提取與壓縮操作的完整指南
- Python實現(xiàn)將Excel轉(zhuǎn)換為高保真圖片
- Python實現(xiàn)鏈接下載圖片并存儲到Excel中
- 使用Python從Excel文件中自動提取圖片的全過程
- Python實現(xiàn)在Excel中動態(tài)插入與刪除圖片的完整指南
- 通過Python在Excel中添加或刪除圖片的操作流程
- Python利用Spire.XLS for Python將Excel轉(zhuǎn)換為圖片
- Python實現(xiàn)批量識別圖片文字并保存到excel中
- Python實現(xiàn)將Excel中圖表形狀等內(nèi)容導(dǎo)出為圖片
相關(guān)文章
正確理解python中的關(guān)鍵字“with”與上下文管理器
這篇文章主要介紹了關(guān)于python中關(guān)鍵字"with"和上下文管理器的相關(guān)資料,文中介紹的非常詳細,相信對大家學習或者使用python具有一定的參考價值,需要的朋友們下面來一起看看吧。2017-04-04
在python plt圖表中文字大小調(diào)節(jié)的方法
今天小編就為大家分享一篇在python plt圖表中文字大小調(diào)節(jié)的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-07-07
Python實現(xiàn)的網(wǎng)頁截圖功能【PyQt4與selenium組件】
這篇文章主要介紹了Python實現(xiàn)的網(wǎng)頁截圖功能,結(jié)合實例形式分別描述了使用PyQt4組件與selenium組件進行網(wǎng)頁截圖操作的相關(guān)實現(xiàn)技巧與注意事項,需要的朋友可以參考下2018-07-07
Python詳細對比講解break和continue區(qū)別
這篇文章主要介紹了python循環(huán)控制語句 break 與 continue,break就像是終止按鍵,不管執(zhí)行到哪一步,只要遇到break,不管什么后續(xù)步驟,直接跳出當前循環(huán)2022-06-06
Python中POST調(diào)用Restful接口示例
這篇文章主要介紹了Python之POST調(diào)用Restful接口示例,本文結(jié)合示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-02-02
Python中DataFrame與內(nèi)置數(shù)據(jù)結(jié)構(gòu)相互轉(zhuǎn)換的實現(xiàn)
pandas?支持我們從?Excel、CSV、數(shù)據(jù)庫等不同數(shù)據(jù)源當中讀取數(shù)據(jù),來構(gòu)建?DataFrame。但有時數(shù)據(jù)并不來自這些外部數(shù)據(jù)源,這就涉及到了?DataFrame?和?Python?內(nèi)置數(shù)據(jù)結(jié)構(gòu)之間的相互轉(zhuǎn)換,本文就來和大家詳細聊聊2023-02-02
PyCharm設(shè)置Ipython交互環(huán)境和宏快捷鍵進行數(shù)據(jù)分析圖文詳解
這篇文章主要介紹了PyCharm設(shè)置Ipython交互環(huán)境和宏快捷鍵進行數(shù)據(jù)分析圖文詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-04-04
python代碼實現(xiàn)學生信息管理系統(tǒng)
這篇文章主要為大家詳細介紹了python代碼實現(xiàn)學生信息管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-05-05

