<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          python玩轉excel——如何讀取、寫入圖片

          共 8271字,需瀏覽 17分鐘

           ·

          2020-12-25 03:35

          留言有禮,每天都會從留言中選出三位抽取6.6元紅包


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

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

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

          • Python讀取Excel圖片
          • Python寫入Excel圖片

          涉及的Python模塊有以下幾個

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

          ? 一、準備

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

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

          在下載的過程中,有些包是比較大的,會出現(xiàn)超時time out的報錯現(xiàn)象。這里介紹幾個國內的鏡像,大家可以嘗試其中一個,速度會比單純的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?網(wǎng)址

          清華鏡像舉例

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

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

          ??二、Python讀取Excel圖片

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

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

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

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

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

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

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

          2.1? 方法一

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

          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()??#關閉文件,必須有,釋放內存

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

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

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

          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函數(shù)用于返回指定的文件夾包含的文件或文件夾的名字的列表。再用for循環(huán)遍歷這個列表,將.xlsx結尾的改為.zip結尾。

          同時再用os.rename()函數(shù)重命名對應的文件夾。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()函數(shù)來獲取在這個路徑下的所有文件名字。

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

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

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

          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循環(huán)遍歷我們已經(jīng)處理過的list——dir列表,得到zip文件名,再用zipfile.ZipFile()函數(shù)來打開我們zip文件。其中azip.namelist()函數(shù)是用來裝zip文件里面所有文件的文件名列表。

          接下來可以進入到zip文件中仔細觀察,可以發(fā)現(xiàn)我們所需要的圖片在'xl/media/'這個路徑下,有了這個目標后,我們再用for循環(huán)遍歷zip文件里的所有文件,找到路徑下的圖片。

          第二個for循環(huán)需要注意幾點

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

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

          2.2? 方法二

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

          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()

          效果呈現(xiàn):

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

          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循環(huán)的目的是遍歷所選Excel文件中的工作表,我們有四張圖片放在example.xlsx的四個不同的工作表里。第二個for循環(huán)是用來遍歷每個工作表中的圖片并復制到粘貼板中的。

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

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

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

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

          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中圖片的兩種方法,大家可以根據(jù)自己的情況來選擇如惡化提取Excel中的圖片。

          ? 二、Python寫入Excel圖片

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

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

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

          參數(shù)介紹如下:

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

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

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

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

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

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

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

          代碼如下:

          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:\數(shù)據(jù).xlsx')
          title?=?['日期','收盤價']
          df?=?df[title]
          plt.plot(df['日期'],df['收盤價'])
          plt.gcf().autofmt_xdate()#自動調整角度
          plt.savefig(r'D:\數(shù)據(jù)折線圖.jpg')

          Python畫出的圖如下:

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

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


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

          下面使用.insert_image插入圖片。

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

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


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

          workbook.close()

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

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

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


          -END-

          昨日留言中獎名單

          以上三位小伙伴,加小編微信:yumeko370?領取小小紅包一份哦!



          1、PyCharm中七大神級插件

          2、想學畫畫?python滿足你!

          3、Github Star 7.6K!高精度開源集成數(shù)據(jù)標注、合成功能的OCR模塊,強烈推薦!


          轉發(fā),點贊,在看,安排一下?
          瀏覽 76
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产天美传媒 | 91 丝袜一区二区三区 | 91丝袜视频| 天堂网www啊啊啊啊啊啊 | 波多野结衣免费AV |