如何用Python讀取Excel中圖片?又如何用Python往Excel中寫入圖片?

2021-03-02 數據森麟

大家好,在使用Python進行辦公自動化操作時,一定少不了與Excel表格的交互,我們通常是用pandas處理表格數據,但大多數情況下,都是讀取表格中的數值進行分析。

那麼你知道如何使用Python讀取Excel中的圖片?又如何使用Python直接往Excel中寫入圖片?甚至使用Python製作一個Excel可視化大屏?

因為圖片的存儲格式與數字數據格式不一樣,所以實現起來稍顯複雜,本文就將對以下兩個部分進行深入講解:

涉及的Python模塊有以下幾個

由於此次包比較多,我們需要在命令行中使用pip進行安裝

pip install pillow   #這是對模塊PTL的安裝
pip install pypiwin32    #這是對win32的安裝
pip install os 
pip install zipfile
pip install numpy
pip install xlsxwriter

在下載的過程中,有些包是比較大的,會出現超時time out的報錯現象。這裡介紹幾個國內的鏡像,大家可以嘗試其中一個,速度會比單純的pip快10倍不止。地址如下:

http://pypi.douban.com/simple/ 豆瓣
http://mirrors.aliyun.com/pypi/simple/ 阿里
http://pypi.hustunique.com/simple/ 華中理工大學
http://pypi.sdutlinux.org/simple/ 山東理工大學
http://pypi.mirrors.ustc.edu.cn/simple/ 中國科學技術大學
https://pypi.tuna.tsinghua.edu.cn/simple 清華

代碼如下:

pip install 模塊名 -i 網址

清華鏡像舉例

pip install pillow -i https://pypi.tuna.tsinghua.edu.cn/simple

注意:如果是原生態的cmd窗口安裝的,會提示加個--user命令,讀者按照指示即可。

上面說過,Python讀取Excel圖片有兩種方法

第一種:將xlsx後綴名改為zip形式,即進行壓縮。而後讀取裡面存儲圖片的文件,將裡面的圖片取出來。

第二種:用提取到粘貼板中的方法將圖片保存到JPG、PNG等格式中

兩種方法各有缺點和優點,第一種方法缺點是代碼量比較長,優點是萬能,Excel的所有格式都可以運用。

第二種的優點是代碼量少,缺點是對於一些xlsx的文件運用不了

首先我們先講解第一種方法,之後在講解第二種方法時,大家可以進行對比!

講解之前我們用的是以下的example.xlsx文件,裡面有四個工作表,每個工作表都有一張數據可視化圖。例如工作表3中的氣泡圖如下:

和之前的文章一樣,我們先給出全部代碼與效果圖之後再進行講解

import os
import zipfile
import os
from PIL import Image
import numpy as np 
path = r'D:'
count = 1
for file in os.listdir(path):
    new_file = file.replace(".xlsx",".zip")
    os.rename(os.path.join(path,file),os.path.join(path,new_file))
    count+=1
print('總共有'+str(count)+'個文件夾')
number = 0
craterDir = "D:/"  # 存放zip文件的文件夾路徑
saveDir = "D:/"  # 存放圖片的路徑 
list_dir = os.listdir(craterDir) 
for i in range(len(list_dir)):
    if 'zip' not in list_dir[i]:
        list_dir[i] = ''
while '' in list_dir:
    list_dir.remove('')    
for zip_name in list_dir:
    print(zip_name)
    azip = zipfile.ZipFile(craterDir + zip_name)
    namelist = (azip.namelist())
 
    for idx in range(0,len(namelist)):
        if namelist[idx][:9] == 'xl/media/':#圖片是在這個路徑下
            img_name = saveDir + str(number)+'.jpg'
            f = azip.open(namelist[idx])
            img = Image.open(f)
            img = img.convert("RGB")
            img.save(img_name,"JPEG")
            number += 1
azip.close()  #關閉文件,必須有,釋放內存

效果展現如下:

可以看到example.xlsx裡面的四張工作表裡的圖片都提取出來,保存在本地。

現在我們進行代碼解析,首先,引入相關包

import os
import zipfile
from PIL import Image
import numpy as np 

其次,就是將xlsx格式結尾的文件夾進行壓縮,轉化成zip結尾的文件

path = r'D:'   #excel文件位置
count = 1
for file in os.listdir(path):
    new_file = file.replace(".xlsx",".zip")
    os.rename(os.path.join(path,file),os.path.join(path,new_file))
    count+=1 

這裡首先設置了example.xlsx的文件位置,在D盤的根目錄,讀者需要做調整的話在path那行代碼修改即可。

其次用os模塊的listdir函數用於返回指定的文件夾包含的文件或文件夾的名字的列表。再用for循環遍歷這個列表,將.xlsx結尾的改為.zip結尾。

同時再用os.rename()函數重命名對應的文件夾。count是用來告訴用戶這個文件夾有多少個文件的,用於檢驗。

最後,就是在這些壓縮過後的文件中,提取圖片。代碼如下

number = 0
craterDir = "D:/"  # 存放zip文件的文件夾路徑
saveDir = "D:/"  # 存放圖片的路徑 
list_dir = os.listdir(craterDir) # 獲取所有的文件名

for i in range(len(list_dir)):
    if 'zip' not in list_dir[i]:
        list_dir[i] = ''
while '' in list_dir:
    list_dir.remove('')   

下面是代碼解析

首先,number=0是用來最後命名圖片的。craterDir是指存放zip的文件夾路徑,saveDir指存放提取後的圖片的指定路徑。用os.listdir()函數來獲取在這個路徑下的所有文件名字。

這裡強調下,本章代碼採用的路徑,除了上面講過的path外,其他都用絕對路徑,因為如os模塊和zipfile模塊,這些模塊用絕對路徑更不會報錯。

下面用一個for循環加個while循環的用途是剔除不是.zip結尾的文件夾。這時有讀者會問,用for循環加個列表del函數不香嗎?

其實是不行的,大家可以去嘗試一下。原因是,你每次del廣域網一個列表的元素,列表的數量值會一直在變而不是固定的,這樣就會導致超出索引的錯誤。

for zip_name in list_dir:
    print(zip_name)
    # 默認模式r,讀
    azip = zipfile.ZipFile(craterDir + zip_name)
    # 返回所有文件夾和文件
    namelist = (azip.namelist())
 
    for idx in range(0,len(namelist)):
        if namelist[idx][:9] == 'xl/media/':#圖片是在這個路徑下
            img_name = saveDir + str(number)+'.jpg'
            f = azip.open(namelist[idx])
            img = Image.open(f)
            img = img.convert("RGB")
            img.save(img_name,"JPEG")
            number += 1
azip.close()  #關閉文件,必須有,釋放內存

最後就是讀取zip文件中的圖片。用for循環遍歷我們已經處理過的list——dir列表,得到zip文件名,再用zipfile.ZipFile()函數來打開我們zip文件。其中azip.namelist()函數是用來裝zip文件裡面所有文件的文件名列表。

接下來可以進入到zip文件中仔細觀察,可以發現我們所需要的圖片在'xl/media/'這個路徑下,有了這個目標後,我們再用for循環遍歷zip文件裡的所有文件,找到路徑下的圖片。

第二個for循環需要注意幾點

azip.open()是zipfile模塊裡的打開命令。相對應的,就有azip.close()這個命令,這個命令再整個程序運行完後必須運訓,因為不僅可以清理所佔空間,而且如果你需要還原xlsx文件格式的話,你就必須得關閉,不然會報錯。

Image.open()是模塊Pillow模塊的讀取圖片函數,也算是我們本章最重要的函數之一了,與其搭配的是Image.save()函數,是用來存儲的。中間插著一段代碼img.convert("RGB"),這個一般都是要用到的,我們存儲的圖片大多數是有色的,也就是RGB圖像,如果是黑白的話就要調一下參數。有興趣的讀者可以自行查閱文獻。

接下來講解第二種方法,先上代碼

from PIL import ImageGrab
import win32com.client as win32

excel = win32.gencache.EnsureDispatch('Excel.Application')
workbook = excel.Workbooks.Open(r'D:\example.xlsx')

num = 1
for sheet in workbook.Worksheets:
    for i, shape in enumerate(sheet.Shapes):
        if shape.Name.startswith('Picture'):
            shape.Copy()
            image = ImageGrab.grabclipboard()   
            image.convert('RGB').save(r'D:\{}.jpg'.format(num), 'jpeg')
            num+=1
excel.Quit()

效果呈現:

從上圖可以看到,與方法一的效果相比,基本一致,除了沒有進行壓縮,下面簡單說一下代碼

from PIL import ImageGrab
import win32com.client as win32
excel = win32.gencache.EnsureDispatch('Excel.Application')
workbook = excel.Workbooks.Open(r'D:\example.xlsx')

首先先引入方法二相關的模塊,第三行代碼是引入模塊win32中對Excel中的運用程序。第四行和方法一一樣是讀取D盤根目錄下的example.xlsx文件。

num = 1
for sheet in workbook.Worksheets:
    for i, shape in enumerate(sheet.Shapes):
        if shape.Name.startswith('Picture'):
            shape.Copy()
            image = ImageGrab.grabclipboard()   
            image.convert('RGB').save(r'D:\{}.jpg'.format(num), 'jpeg')
            num+=1
excel.Quit()

第一行num=1,是用來為下面存儲圖片的圖片命名的

接下來就是進行for嵌套for,第一個for循環的目的是遍歷所選Excel文件中的工作表,我們有四張圖片放在example.xlsx的四個不同的工作表裡。第二個for循環是用來遍歷每個工作表中的圖片並複製到粘貼板中的。

其中,enumerate()函數是用於將一個可遍歷的數據對象(如列表、元組或字符串)組合為一個索引序列,同時列出數據和數據下標,一般用在 for 循環當中。這裡的意思就是存放每張圖片數據信息的索引。i是數據下標,shape是數據

shape.Name.startswith('Picture')是判斷獲到的shape裡面名字信息中的開頭是否符合'pitcure',如果是,則返回True。

shape.Copy()函數是對一個一個字典的淺複製(拷貝)。簡單來說就是只在程序中的複製。

ImageGrab.grabclipboard()函數是方法二的精髓,這個函數是抓取當前剪貼板的快照,返回一個模式為「RGB」的圖像或者文件名稱的列表。如果剪貼板不包括圖像數據,這個函數返回空。讀者可以使用函數isinstance()來檢查該函數返回的是一個有效圖像對象或者其他數據。

image.convert('RGB').save(r'D:\{}.jpg'.format(num), 'jpeg')這段語句,是將得到的image以jpg的格式存儲。這裡的jpeg其實就是jpg,只不過模塊裡以jpeg代替jpg。

注意,這裡必須用convert('RGB'),如果不使用.convert('RGB')進行轉換的話,讀出來的圖像是RGBA四通道的,A通道為透明通道,運出來是沒有圖像顯示的。因此使用convert('RGB')進行通道轉換。

至此,我們就講完了使用Python提取Excel中圖片的兩種方法,大家可以根據自己的情況來選擇如惡化提取Excel中的圖片。

在講完如何用Python提取Excel中圖片之後,下面我們將講解如何用Python將圖片寫入到Excel文件中。

我們常用的模塊是xlsxwriter。這裡先介紹這個模塊的常用插入圖片函數

worksheet.insert_image(row,col,image[,options] :在工作表單元格中插入一張圖片

參數介紹如下:

image(string) - 圖片文件名(含路徑)options(dict) - 可選的圖片位置,縮放,url參數」

同時insert_image()方法接受字典形式的可選參數來定位和縮放圖片。默認值為

{
    'x_offset': 0,    #以像素為單位,可以大於每個單元格的寬度和高度
    'y_offset': 0,
    'x_scale': 1,
    'y_scale': 1,
    'url': None,
    'tip': None,
    'image_data': None,
    'positioning': None,
}

上面幾個參數主要作用如下:

「x_scale和y_scale參數可以用於水平及垂直的縮放圖片。url參數可以為圖片添加超連結/url, tip 參數為含有超連結的圖片提供可選的滑鼠懸停時的提示信息image_data參數用於在io.BytesIO中添加內存中的字節流,一般不用positioning參數可以用來控制圖片對象的位置」

接下來會做一個簡單的程序來演示:

這裡用一份數據簡單的畫出一個折線圖,數據是一份廣匯汽車的股票數據,從8月底到10月底的數據。以收盤價和時間畫一個簡單的折線圖.

代碼如下:

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.style as psl
import xlsxwriter
fig = plt.figure()
df = pd.read_excel(r'D:\數據.xlsx')
title = ['日期','收盤價']
df = df[title]
plt.plot(df['日期'],df['收盤價'])
plt.gcf().autofmt_xdate()#自動調整角度
plt.savefig(r'D:\數據折線圖.jpg')

Python畫出的圖如下:

現在我們要將其插入到一份名為數據image.xlsx的excel文件中,來看看代碼怎麼寫👇

首先使用xlswriter創建一個新Excel文件並添加一個工作表


workbook = xlsxwriter.Workbook(r'D:\數據images.xlsx')
worksheet = workbook.add_worksheet()

下面使用.insert_image插入圖片。

worksheet.write('A2', '插入第一張圖片:')
worksheet.insert_image('B2', r'D:\數據折線圖.jpg')

worksheet.write('A12', '插入第二張即位偏移圖片:')
worksheet.insert_image('B12', r'D:\數據折線圖.jpg', {'x_offset': 15, 'y_offset': 10})


# 插入一張縮放了的圖片。
worksheet.write('A23', '插入第三張縮放了的圖片:')
worksheet.insert_image('B23', r'D:\數據折線圖.jpg', {'x_scale': 0.5, 'y_scale': 0.5})

workbook.close()

最後要注意一定要用workbook.close()才能生成,效果呈現如下

可以看到,我們使用Matplotlib生成的折線圖被插入到我們預定的指定位置中!

至此,本文就結束了,相信你已經學會如何使用Python與Excel圖片之間的交互,並能夠結合具體的需求進行批量操作

數據森麟公眾號的交流群已經建立,許多小夥伴已經加入其中,感謝大家的支持。大家可以在群裡交流關於數據分析&數據挖掘的相關內容,還沒有加入的小夥伴可以掃描下方管理員二維碼,進群前一定要關注公眾號奧,關注後讓管理員幫忙拉進群,期待大家的加入。

管理員二維碼:

相關焦點

  • 如何用Python讀取Excel中圖片?
    那麼你知道如何使用Python讀取Excel中的圖片?又如何使用Python直接往Excel中寫入圖片?甚至使用Python製作一個Excel可視化大屏?因為圖片的存儲格式與數字數據格式不一樣,所以實現起來稍顯複雜,本文就將對以下兩個部分進行深入講解:Python讀取Excel圖片Python寫入Excel圖片
  • 如何用python實現excel中的vlookup功能?
    因為刀哥是python初學者,對於需要用到的知識點,如果以前學過的要再複習一下,年紀大了嘛記性比較差,沒學過的新知識點要先學習一下,邊學邊用,所以做的速度比較慢,但是好在,哪怕慢,只要每天進步一點點,都是好的。今天這篇分享,就是刀哥在做的過程中,遇到的其中一個知識點,即用python來實現excel中的vlookup函數功能。
  • 14-用Python 讀寫 Excel 文件
    數據量可能會很大需要跨平臺要讀取 XLS 或 XLSX 文件要生成 XLS 文件需要的功能不太複雜需要跨平臺要處理 XLSX 文件需要修改已有文件,或者在寫入過程中需要不斷修改需要的功能比較複雜數據量可能會很大需要跨平臺需要處理各種文件格式需要用到特別複雜的功能在修改文件時,不希望對原有信息造成任何意外破壞
  • 如何在Visual Studio中創建excel並讀取數據
    >xlrd技術pythondjangoexcel在Visual Studio開發工具中,創建python項目,然後安裝xlwt和xlrd第三方庫,使用xlwt創建excel文件並寫入數據,使用xlrd讀取excel文件中的數據。
  • 【校園雜工】Python腳本處理檔案圖片之完結篇:Python處理Excel
    仔細觀察 xlwt的文檔,發現 workbook方法有一個encoding參數用來設置excel文件的編碼,默認是ascii碼,我們也可以指定為utf-8編碼,如果excel中有中文。># 保存文件ws.save('amazing-python.xls')注意,我注釋掉了中間負責遍歷所有圖片的代碼,因為在測試 xlwt庫使用的過程中,我們不需要對圖片進行處理,這也算是調試代碼的一個小技巧把。
  • 如何從excel中讀取多個工作表
    因為默認都是假設一個excel只有一個sheet,所以我一開始也沒考慮到這種情況。不過不用怕,明白問題就能找到解決辦法。我用谷歌搜索How to read mutiple sheets from one excel in Python?打開stackoverflow,瀏覽了一番,看到這個解答。
  • python操作excel:批量生成超連結
    excel設置超連結的函數是HYPERLINK,這裡用python批量生成超連結的思想其實很簡單,就是將公式寫入excel就行。
  • PYTHON-1 根據excel中的url 批量下載圖片
    學習分享:包括但不限於計算機學習、數學、英語等;影音分享:我個人喜歡的影視作品,以及音樂;今天主要分享我前段時間為了解決批量下載圖片寫的一段python代碼過程。讀取excel文件存儲路徑並讀取文件內容;按照文件中一級分類->二級分類批量創建文件夾,並根據圖片的url下載圖片(for循環+if判斷);代碼示例:import xlrdimport requestsimport numpy as npimport pandas as pdimport
  • Python數據分析:pandas讀取和寫入數據
    我的公眾號是關於自己在數據分析/挖掘學習過程中的一些技術和總結分享,文章會持續更新......繼續深入學習pandas相關操作,數據讀取寫入、分組、合併,轉換等等。前面一篇文章裡已經寫了關於描述性統計以及常用的基本操作。接下來的一段時間裡,我將陸續地去掌握並輸出。這篇文章是關於數據讀取與寫入的知識點。
  • PDF轉EXCEL,python的這個技能知道嗎?
    當在pdf上看到自己想用的表格,卻無法將其複製下來的時候,只能默默地打開excel對照著pdf表格的形式敲打出來,既費時又費力!這裡介紹如何用python程序將pdf上的表格自動轉化為excel表!,可以用它對excel進行創建表單、寫入指定單元格、指定單元格樣式等人工實現的功能等一系列操作。
  • 教你如何用python輕輕鬆鬆操作Excel、Word、CSV,一文就夠了,趕緊碼住!!!
    修改 excel上面說了寫入和讀取 Excel 內容,接下來我們就說下更新修改 Excel 該如何操作,修改時就需要用到 xlutils 中的方法了。寫入 Word平時我們在操作 Word 寫文檔的時候,一般分為幾部分:標題、章節、段落、圖片、表格、引用以及項目符號編號等。下面我們就按這幾部分如何用 Python 操作來一一介紹。
  • Python讀取CSV和Excel
    1普通方法讀取: with open("fileName.csv") as file:   for line in  file:       print line 2用CSV標準庫讀取: import csvcsv_reader = csv.reader(open("fileName.csv"))for row in csv_reader:     print row 3用pandas讀取: import pandas as
  • python+xlrd+xlwt操作excel
    小強python全棧自動化測試培訓班招生中,預計開課時間為18年3月份在2017年10月之前報名並繳納全部費用的童鞋優惠
  • n種方式教你用python讀寫excel等數據文件
    下面整理下python有哪些方式可以讀寫數據文件。1. read、readline、readlinesread()  :一次性讀取整個文件內容。推薦使用read(size)方法,size越大運行時間越長readline()  :每次讀取一行內容。
  • 文職美女上班手動用Excel表格太麻煩,當學會python後easy操作
    通過程序操作excel表格是編程中比較常見的操作,python本身不能直接操作excel,需要安裝第三方的模塊來實現excel的操作。Python中可以操作excel模塊主要有:1、xlrd 模塊實現exlcel表格讀取2、xlwd 模塊實現excel表格創建和寫入3、pandas模塊也可以實現excel常規操作
  • Python讀寫Excel表格,就是這麼簡單粗暴又好用
    python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。可從這裡下載https://pypi.python.org/pypi。下面分別記錄python讀和寫excel。
  • n種方式教你用Python讀寫Excel等數據文件
    下面整理下python有哪些方式可以讀寫數據文件。1. read、readline、readlinesread()  :一次性讀取整個文件內容。推薦使用read(size)方法,size越大運行時間越長readline()  :每次讀取一行內容。
  • 如何用Python輕鬆搞定Excel日常任務
    本文將告訴你,這三項Excel日常任務,如何用Python輕鬆搞定。首先導入Pandas並根據工作簿中可用的工作表加載兩個dataframe,稱它們為sales和states。import pandas as pdsales = pd.read_excel('https://github.com/datagy/mediumdata/raw/master/pythonexcel.xlsx', sheet_name ='sales')states = pd.read_excel
  • Python讀寫Excel表格,就是這麼簡單粗暴又好用(文末送書)
    python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。可從這裡下載https://pypi.python.org/pypi。下面分別記錄python讀和寫excel。
  • 詳解Python操作Excel文件
    前言本篇文章主要總結了一下利用python操作Excel文件的第三方庫和方法。常見庫簡介1.xlrdxlrd是一個從Excel文件讀取數據和格式化信息的庫,支持.xls以及.xlsx文件。4.xlwingsxlwings是一個可以實現從Excel調用Python,也可在python中調用Excel的庫。地址:http://docs.xlwings.org/en/stable/index.html4、強大的轉換器可以處理大部分數據類型,包括在兩個方向上的numpy array和pandas DataFrame。