自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何用Python讀取Excel中圖片?又如何用Python往Excel中寫(xiě)入圖片?

開(kāi)發(fā) 后端
大家好,在使用Python進(jìn)行辦公自動(dòng)化操作時(shí),一定少不了與Excel表格的交互,我們通常是用pandas處理表格數(shù)據(jù),但大多數(shù)情況下,都是讀取表格中的數(shù)值進(jìn)行分析。

 [[356846]]

本文轉(zhuǎn)載自微信公眾號(hào)「早起Python」,作者劉早起。轉(zhuǎn)載本文請(qǐng)聯(lián)系早起Python公眾號(hào)。

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

那么你知道如何使用Python讀取Excel中的圖片?又如何使用Python直接往Excel中寫(xiě)入圖片?甚至使用Python制作一個(gè)Excel可視化大屏?

因?yàn)閳D片的存儲(chǔ)格式與數(shù)字?jǐn)?shù)據(jù)格式不一樣,所以實(shí)現(xiàn)起來(lái)稍顯復(fù)雜,本文就將對(duì)以下兩個(gè)部分進(jìn)行深入講解:

  • Python讀取Excel圖片
  • Python寫(xiě)入Excel圖片

涉及的Python模塊有以下幾個(gè)

  • PIL
  • win32
  • os
  • zipfile
  • numpy
  • xlsxwriter

一、準(zhǔn)備

由于此次包比較多,我們需要在命令行中使用pip進(jìn)行安裝

  1. pip install pillow   #這是對(duì)模塊PTL的安裝 
  2. pip install pypiwin32    #這是對(duì)win32的安裝 
  3. pip install os  
  4. pip install zipfile 
  5. pip install numpy 
  6. pip install xlsxwriter 

在下載的過(guò)程中,有些包是比較大的,會(huì)出現(xiàn)超時(shí)time out的報(bào)錯(cuò)現(xiàn)象。這里介紹幾個(gè)國(guó)內(nèi)的鏡像,大家可以嘗試其中一個(gè),速度會(huì)比單純的pip快10倍不止。地址如下:

  1. http://pypi.douban.com/simple/ 豆瓣 
  2. http://mirrors.aliyun.com/pypi/simple/ 阿里 
  3. http://pypi.hustunique.com/simple/ 華中理工大學(xué) 
  4. http://pypi.sdutlinux.org/simple/ 山東理工大學(xué) 
  5. http://pypi.mirrors.ustc.edu.cn/simple/ 中國(guó)科學(xué)技術(shù)大學(xué) 
  6. https://pypi.tuna.tsinghua.edu.cn/simple 清華 

代碼如下:

  1. pip install 模塊名 -i 網(wǎng)址 

以清華鏡像舉例

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

注意:如果是原生態(tài)的cmd窗口安裝的,會(huì)提示加個(gè)--user命令,讀者按照指示即可。

二、Python讀取Excel圖片

上面說(shuō)過(guò),Python讀取Excel圖片有兩種方法。

第一種:將xlsx后綴名改為zip形式,即進(jìn)行壓縮。而后讀取里面存儲(chǔ)圖片的文件,將里面的圖片取出來(lái)。

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

兩種方法各有缺點(diǎn)和優(yōu)點(diǎn),第一種方法缺點(diǎn)是代碼量比較長(zhǎng),優(yōu)點(diǎn)是萬(wàn)能,Excel的所有格式都可以運(yùn)用。

第二種的優(yōu)點(diǎn)是代碼量少,缺點(diǎn)是對(duì)于一些xlsx的文件運(yùn)用不了。

首先我們先講解第一種方法,之后在講解第二種方法時(shí),大家可以進(jìn)行對(duì)比!

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

2.1 方法一

和之前的文章一樣,我們先給出全部代碼與效果圖之后再進(jìn)行講解

  1. import os 
  2. import zipfile 
  3. import os 
  4. from PIL import Image 
  5. import numpy as np  
  6. path = r'D:' 
  7. count = 1 
  8. for file in os.listdir(path): 
  9.     new_file = file.replace(".xlsx",".zip"
  10.     os.rename(os.path.join(path,file),os.path.join(path,new_file)) 
  11.     count+=1 
  12. print('總共有'+str(count)+'個(gè)文件夾'
  13. number = 0 
  14. craterDir = "D:/"  # 存放zip文件的文件夾路徑 
  15. saveDir = "D:/"  # 存放圖片的路徑  
  16. list_dir = os.listdir(craterDir)  
  17. for i in range(len(list_dir)): 
  18.     if 'zip' not in list_dir[i]: 
  19.         list_dir[i] = '' 
  20. while '' in list_dir: 
  21.     list_dir.remove('')     
  22. for zip_name in list_dir: 
  23.     print(zip_name) 
  24.     azip = zipfile.ZipFile(craterDir + zip_name) 
  25.     namelist = (azip.namelist()) 
  26.   
  27.     for idx in range(0,len(namelist)): 
  28.         if namelist[idx][:9] == 'xl/media/':#圖片是在這個(gè)路徑下 
  29.             img_name = saveDir + str(number)+'.jpg' 
  30.             f = azip.open(namelist[idx]) 
  31.             img = Image.open(f) 
  32.             img = img.convert("RGB"
  33.             img.save(img_name,"JPEG"
  34.             number += 1 
  35. azip.close()  #關(guān)閉文件,必須有,釋放內(nèi)存 

效果展現(xiàn)如下:

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

現(xiàn)在我們進(jìn)行代碼解析,首先,引入相關(guān)包

  1. import os 
  2. import zipfile 
  3. from PIL import Image 
  4. import numpy as np  

其次,就是將xlsx格式結(jié)尾的文件夾進(jìn)行壓縮,轉(zhuǎn)化成zip結(jié)尾的文件

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

這里首先設(shè)置了example.xlsx的文件位置,在D盤(pán)的根目錄,讀者需要做調(diào)整的話在path那行代碼修改即可。

其次用os模塊的listdir函數(shù)用于返回指定的文件夾包含的文件或文件夾的名字的列表。再用for循環(huán)遍歷這個(gè)列表,將.xlsx結(jié)尾的改為.zip結(jié)尾。

同時(shí)再用os.rename()函數(shù)重命名對(duì)應(yīng)的文件夾。count是用來(lái)告訴用戶這個(gè)文件夾有多少個(gè)文件的,用于檢驗(yàn)。

最后,就是在這些壓縮過(guò)后的文件中,提取圖片。代碼如下

  1. number = 0 
  2. craterDir = "D:/"  # 存放zip文件的文件夾路徑 
  3. saveDir = "D:/"  # 存放圖片的路徑  
  4. list_dir = os.listdir(craterDir) # 獲取所有的文件名 
  5.  
  6. for i in range(len(list_dir)): 
  7.     if 'zip' not in list_dir[i]: 
  8.         list_dir[i] = '' 
  9. while '' in list_dir: 
  10.     list_dir.remove('')    

下面是代碼解析:

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

這里強(qiáng)調(diào)下,本章代碼采用的路徑,除了上面講過(guò)的path外,其他都用絕對(duì)路徑,因?yàn)槿鏾s模塊和zipfile模塊,這些模塊用絕對(duì)路徑更不會(huì)報(bào)錯(cuò)。

下面用一個(gè)for循環(huán)加個(gè)while循環(huán)的用途是剔除不是.zip結(jié)尾的文件夾。這時(shí)有讀者會(huì)問(wèn),用for循環(huán)加個(gè)列表del函數(shù)不香嗎?

其實(shí)是不行的,大家可以去嘗試一下。原因是,你每次del廣域網(wǎng)一個(gè)列表的元素,列表的數(shù)量值會(huì)一直在變而不是固定的,這樣就會(huì)導(dǎo)致超出索引的錯(cuò)誤。

  1. for zip_name in list_dir: 
  2.     print(zip_name) 
  3.     # 默認(rèn)模式r,讀 
  4.     azip = zipfile.ZipFile(craterDir + zip_name) 
  5.     # 返回所有文件夾和文件 
  6.     namelist = (azip.namelist()) 
  7.   
  8.     for idx in range(0,len(namelist)): 
  9.         if namelist[idx][:9] == 'xl/media/':#圖片是在這個(gè)路徑下 
  10.             img_name = saveDir + str(number)+'.jpg' 
  11.             f = azip.open(namelist[idx]) 
  12.             img = Image.open(f) 
  13.             img = img.convert("RGB"
  14.             img.save(img_name,"JPEG"
  15.             number += 1 
  16. azip.close()  #關(guān)閉文件,必須有,釋放內(nèi)存 

最后就是讀取zip文件中的圖片。用for循環(huán)遍歷我們已經(jīng)處理過(guò)的list——dir列表,得到zip文件名,再用zipfile.ZipFile()函數(shù)來(lái)打開(kāi)我們zip文件。其中azip.namelist()函數(shù)是用來(lái)裝zip文件里面所有文件的文件名列表。

接下來(lái)可以進(jìn)入到zip文件中仔細(xì)觀察,可以發(fā)現(xiàn)我們所需要的圖片在'xl/media/'這個(gè)路徑下,有了這個(gè)目標(biāo)后,我們?cè)儆胒or循環(huán)遍歷zip文件里的所有文件,找到路徑下的圖片。

第二個(gè)for循環(huán)需要注意幾點(diǎn):

azip.open()是zipfile模塊里的打開(kāi)命令。相對(duì)應(yīng)的,就有azip.close()這個(gè)命令,這個(gè)命令再整個(gè)程序運(yùn)行完后必須運(yùn)訓(xùn),因?yàn)椴粌H可以清理所占空間,而且如果你需要還原xlsx文件格式的話,你就必須得關(guān)閉,不然會(huì)報(bào)錯(cuò)。

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

2.2 方法二

接下來(lái)講解第二種方法,先上代碼

  1. from PIL import ImageGrab 
  2. import win32com.client as win32 
  3.  
  4. excel = win32.gencache.EnsureDispatch('Excel.Application'
  5. workbook = excel.Workbooks.Open(r'D:\example.xlsx'
  6.  
  7. num = 1 
  8. for sheet in workbook.Worksheets: 
  9.     for i, shape in enumerate(sheet.Shapes): 
  10.         if shape.Name.startswith('Picture'): 
  11.             shape.Copy() 
  12.             image = ImageGrab.grabclipboard()    
  13.             image.convert('RGB').save(r'D:\{}.jpg'.format(num), 'jpeg'
  14.             num+=1 
  15. excel.Quit() 

效果呈現(xiàn):

從上圖可以看到,與方法一的效果相比,基本一致,除了沒(méi)有進(jìn)行壓縮,下面簡(jiǎn)單說(shuō)一下代碼

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

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

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

第一行num=1,是用來(lái)為下面存儲(chǔ)圖片的圖片命名的

接下來(lái)就是進(jìn)行for嵌套for,第一個(gè)for循環(huán)的目的是遍歷所選Excel文件中的工作表,我們有四張圖片放在example.xlsx的四個(gè)不同的工作表里。第二個(gè)for循環(huán)是用來(lái)遍歷每個(gè)工作表中的圖片并復(fù)制到粘貼板中的。

其中,enumerate()函數(shù)是用于將一個(gè)可遍歷的數(shù)據(jù)對(duì)象(如列表、元組或字符串)組合為一個(gè)索引序列,同時(shí)列出數(shù)據(jù)和數(shù)據(jù)下標(biāo),一般用在 for 循環(huán)當(dāng)中。這里的意思就是存放每張圖片數(shù)據(jù)信息的索引。i是數(shù)據(jù)下標(biāo),shape是數(shù)據(jù)

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

shape.Copy()函數(shù)是對(duì)一個(gè)一個(gè)字典的淺復(fù)制(拷貝)。簡(jiǎn)單來(lái)說(shuō)就是只在程序中的復(fù)制。

ImageGrab.grabclipboard()函數(shù)是方法二的精髓,這個(gè)函數(shù)是抓取當(dāng)前剪貼板的快照,返回一個(gè)模式為“RGB”的圖像或者文件名稱(chēng)的列表。如果剪貼板不包括圖像數(shù)據(jù),這個(gè)函數(shù)返回空。讀者可以使用函數(shù)isinstance()來(lái)檢查該函數(shù)返回的是一個(gè)有效圖像對(duì)象或者其他數(shù)據(jù)。

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

注意,這里必須用convert('RGB'),如果不使用.convert('RGB')進(jìn)行轉(zhuǎn)換的話,讀出來(lái)的圖像是RGBA四通道的,A通道為透明通道,運(yùn)出來(lái)是沒(méi)有圖像顯示的。因此使用convert('RGB')進(jìn)行通道轉(zhuǎn)換。

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

二、Python寫(xiě)入Excel圖片

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

我們常用的模塊是xlsxwriter。這里先介紹這個(gè)模塊的常用插入圖片函數(shù)

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

參數(shù)介紹如下:

  • row(int) - 單元格所在的行(從0開(kāi)始)
  • col(int) - 單元格所在的列(從0開(kāi)始)
  • image(string) - 圖片文件名(含路徑)
  • options(dict) - 可選的圖片位置,縮放,url參數(shù)

同時(shí)insert_image()方法接受字典形式的可選參數(shù)來(lái)定位和縮放圖片。默認(rèn)值為

  1.     'x_offset': 0,    #以像素為單位,可以大于每個(gè)單元格的寬度和高度 
  2.     'y_offset': 0, 
  3.     'x_scale': 1, 
  4.     'y_scale': 1, 
  5.     'url': None, 
  6.     'tip': None, 
  7.     'image_data': None, 
  8.     'positioning': None, 

上面幾個(gè)參數(shù)主要作用如下:

  • x_scale和y_scale參數(shù)可以用于水平及垂直的縮放圖片。
  • url參數(shù)可以為圖片添加超鏈接/url, tip 參數(shù)為含有超鏈接的圖片提供可選的鼠標(biāo)懸停時(shí)的提示信息
  • image_data參數(shù)用于在io.BytesIO中添加內(nèi)存中的字節(jié)流,一般不用
  • positioning參數(shù)可以用來(lái)控制圖片對(duì)象的位置

接下來(lái)會(huì)做一個(gè)簡(jiǎn)單的程序來(lái)演示:

這里用一份數(shù)據(jù)簡(jiǎn)單的畫(huà)出一個(gè)折線圖,數(shù)據(jù)是一份廣匯汽車(chē)的股票數(shù)據(jù),從8月底到10月底的數(shù)據(jù)。以收盤(pán)價(jià)和時(shí)間畫(huà)一個(gè)簡(jiǎn)單的折線圖.

代碼如下:

  1. import pandas as pd 
  2. import matplotlib.pyplot as plt 
  3. import matplotlib.style as psl 
  4. import xlsxwriter 
  5. fig = plt.figure() 
  6. df = pd.read_excel(r'D:\數(shù)據(jù).xlsx'
  7. title = ['日期','收盤(pán)價(jià)'
  8. df = df[title] 
  9. plt.plot(df['日期'],df['收盤(pán)價(jià)']) 
  10. plt.gcf().autofmt_xdate()#自動(dòng)調(diào)整角度 
  11. plt.savefig(r'D:\數(shù)據(jù)折線圖.jpg'

Python畫(huà)出的圖如下:

現(xiàn)在我們要將其插入到一份名為數(shù)據(jù)image.xlsx的excel文件中,來(lái)看看代碼怎么寫(xiě)??

首先使用xlswriter創(chuàng)建一個(gè)新Excel文件并添加一個(gè)工作表。

  1. workbook = xlsxwriter.Workbook(r'D:\數(shù)據(jù)images.xlsx'
  2. worksheet = workbook.add_worksheet() 

下面使用.insert_image插入圖片。

  1. worksheet.write('A2''插入第一張圖片:'
  2. worksheet.insert_image('B2', r'D:\數(shù)據(jù)折線圖.jpg'
  3.  
  4. worksheet.write('A12''插入第二張即位偏移圖片:'
  5. worksheet.insert_image('B12', r'D:\數(shù)據(jù)折線圖.jpg', {'x_offset': 15, 'y_offset': 10}) 
  6.  
  7.  
  8. # 插入一張縮放了的圖片。 
  9. worksheet.write('A23''插入第三張縮放了的圖片:'
  10. worksheet.insert_image('B23', r'D:\數(shù)據(jù)折線圖.jpg', {'x_scale': 0.5, 'y_scale': 0.5}) 
  11.  
  12. workbook.close() 

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

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

至此,本文就結(jié)束了,相信你已經(jīng)學(xué)會(huì)如何使用Python與Excel圖片之間的交互,并能夠結(jié)合具體的需求進(jìn)行批量操作!

 

責(zé)任編輯:武曉燕 來(lái)源: 早起Python
相關(guān)推薦

2011-07-13 14:02:42

OracleExcel

2018-08-24 08:10:10

編程語(yǔ)言Python電子郵件

2017-07-20 21:06:44

PythonExcelSQL

2020-02-21 17:10:12

ExcelPython腳本語(yǔ)言

2019-12-11 15:21:12

PythonExcel瀏覽器

2018-03-27 18:12:12

PythonHTML

2020-07-10 09:49:53

數(shù)據(jù)清理數(shù)據(jù)分析查找異常

2023-02-08 07:09:40

PythonChatGPT語(yǔ)言模型

2021-12-30 22:01:01

Python庫(kù)代碼

2021-08-02 15:02:37

Go Excelize 開(kāi)發(fā)

2019-11-28 09:23:17

Python機(jī)器學(xué)習(xí)數(shù)據(jù)庫(kù)

2018-05-17 10:05:24

運(yùn)行iPadPython

2020-05-09 10:38:31

Python透視表數(shù)據(jù)

2019-09-18 10:07:24

ExcelSQL數(shù)據(jù)庫(kù)

2024-04-25 12:57:17

2020-11-04 09:52:16

Python讀取圖片開(kāi)發(fā)

2020-11-06 17:42:02

Python開(kāi)發(fā)工具

2021-06-02 15:10:20

PythonScrapy視頻

2011-04-21 11:07:29

遨游3

2011-07-22 13:22:10

Java.NETDataTable
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)