日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

win32com 操作excel

發(fā)布時間:2023/12/10 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 win32com 操作excel 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄

打開表格,讀取數(shù)據(jù)

獲取到當(dāng)前已打開的excel (22/9/20)

win32的寫入操作 與 下拉列表(數(shù)據(jù)驗證)

隱藏表(行列)

刷格式?

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

復(fù)制粘貼,快速下拉



使用win32com操作excel有點類似于VBA(雙廚狂喜),這是一個很顧名思義的庫,他的作用是模擬用戶去做一些操作,像一些簡單的例如操作office全家桶完全不在話下。

安裝

pip install pywin32

以下進(jìn)入正文:

打開表格,讀取數(shù)據(jù)

import win32com.clientpath=r'C:\Users\gztsrayz\Desktop\酸奶.xlsx' excel = win32com.client.DispatchEx('Excel.Application') #這個是必備的,使用win32建新excel也需要他 excel.Visible = True #是否可視化 wb = excel.Workbooks.Open(path, UpdateLinks=False, ReadOnly=False)wb1 = excel.Workbooks.Add() #新建excelwb1.Worksheets.Add().Name = '帥比' #新建sheet,.Name 與后面可不寫 ws1 = wb1.Worksheets('帥比')wb.Save() #保存 wb.SaveAs(r'C:xxx/xxx/milk.xlsx') #另存為 wb.Close(False) #關(guān)閉,問就是不保存 #如果你想看到excel溫馨的提示,括號里就別填東西 excel.quit() ws = wb.Worksheets('匯總') #ws = wb.Worksheets(1) #ws = wb.Worksheets[0] #同樣的,通過名字或者位置來指定表#在測試的時候還發(fā)現(xiàn)通過位置選定表時()和[]都可用,但是[]獲取位置是從0開始計

ws.UsedRange.Rows #最大使用行(包括中間的空行),注意某些行若曾經(jīng)存在過數(shù)據(jù) ws.UsedRange.Columns #即單元格被設(shè)置了格式,使用此種方法會被判定為被占用#導(dǎo)致讀出來的行數(shù)可能并不正確 ws.Range("A1").End(-4121).Row # 模擬 ctrl + ↓ ,從此格往下讀到空行,或者跳過空行 ws.Range("A100").End(-4162).Row # ctrl + ↑list0=ws.Range('A2:A5').Value #跨行讀出來是二維元組 sheet1.Range('A2:Z2').AutoFilter(17,"精英干員") #篩選

=========================================================================

獲取到當(dāng)前已打開的excel (22/9/20)

當(dāng)我們打開多個同樣的表時,從第二個開始都會變成只讀模式。

當(dāng)關(guān)掉第一份表,第二份表就會彈出提示,而這個提示會導(dǎo)致我們的代碼報錯

判斷這個excel是否打開,可以利用os遍歷文件夾判斷是否存在臨時文件

for i in os.listdir(path0):if '~$' in i and 'xlsx' in i: #可以用名字判斷,更加準(zhǔn)確breakelse:print('此文件已打開')time.sleep(0.5)sys.exit()

但是這樣只能夠判斷是否打開,而無法接著打開的excel進(jìn)行操作,于是又嘗試了下面這一段代碼

import win32com.client ee = win32com.client.GetActiveObject('Excel.Application') #只能用注冊名 print(ee.name) # ee = ee.Workbooks(1) #當(dāng)只有一個excel時此句可有可無 # print(ee.name) ws =ee.Worksheets(1) ws.Range('A1').Value=============================== if len(ee.Workbooks)>1: #判斷該進(jìn)程下有多少打開的excel文件for i in ee.Workbooks:print(i.name) else:print(ee.Workbooks(1).name)

值得注意的是,我們每次使用win32com打開excel都會生成一個新的進(jìn)程,而人手打開的excel會歸在同一個進(jìn)程下 (此圖中第一個進(jìn)程為人手打開)

而代碼似乎只能識別到第一個進(jìn)程?(后續(xù)我會繼續(xù)嘗試可否識別到第二第三個進(jìn)程)

也就是說若第一個進(jìn)程是以人手打開的情況下,我們可以很輕松的判斷這個文件是否打開,并且接手它。(PS:當(dāng)然這里只是舉個例子,事實上我們每次使用win32com操作完excel都應(yīng)該關(guān)閉創(chuàng)建的excel進(jìn)程,除非有特例如user運行完了不希望退出excel以方便直接觀看)

如果你的第一個進(jìn)程是win32com創(chuàng)建的,哪怕你將它所打開的excel關(guān)閉了,也依然會讀取到這個進(jìn)程,然后報錯

在注釋掉此句代碼之后,我們會獲取到目前活躍的excel文件(即最近一次選中的excel)(僅限在第一個進(jìn)程中)

ee = ee.Workbooks(1)

?通過接手直接打開的excel 而不是使用win32com打開,在關(guān)閉的時候我們可以減去關(guān)閉excel進(jìn)程的這一操作,因為進(jìn)程會在我們關(guān)閉excel時自動結(jié)束。

?=========================================================================

win32的寫入操作 與 下拉列表(數(shù)據(jù)驗證)

list1=[['das'],['hdfg'],['asg'],[456]] list2=[45,132,46] ws.Range('G1:G4').Value=list1 ws.Range('H1:J1').Value=list2#亦或者是 ws.Range(ws.Cells(1,1),ws.Cells(2,2)).Value=[['a','s'],['d','a']]

ws.Range('C1:C5').Validation.Add(Type=3, AlertStyle=1, Operator=1, Formula1="=$G$1:$G$7") # $ 符號不能少 #注意數(shù)據(jù)驗證的源范圍只能在同excel內(nèi) #val = ws.Cells(6,1).Validation #val.Add(Type=3, AlertStyle=1, Operator=1, Formula1="=Sheet1!A1:A5") #val.IgnoreBlank = -1 #val.InCellDropdown = -1 #val.InputTitle = "" #val.ErrorTitle = "" #val.InputMessage = "" #val.ErrorMessage = "" #val.ShowInput = -1 #val.ShowError = -1

=========================================================================?

隱藏表(行列)

ws.Visible= False #隱藏sheet,顯示為True,隱藏為False ws.Range('A:G').EntireColumn.Hidden=True ws.Range('1:5').EntireRow.Hidden=True

=========================================================================?

刷格式?

既然有寫入,那么自然就要刷格式

ws.Range("A1:B1").Interior.ColorIndex=44 #刷單元格顏色 ws.Range("A2").Font.ColorIndex=23 #刷字體顏色 ws.Range('A2:B2').NumberFormatLocal = "@" #設(shè)置單元格格式為文本 ws.Range("A1:B1").Font.Bold = True #加粗 ws.Range("C1:D1").Merge() #合并單元格,合并之后讀寫均需選中第一個單元格ws.Range("A1:T1").Columns.AutoFit() #自動調(diào)節(jié)邊框?qū)挾?#xff0c;有時調(diào)節(jié)出來不準(zhǔn)確,需要手動再校正 ws.Range("A1").ColumnWidth = 40 # 手動設(shè)置寬度

?ps : 這個B列就是我說的時靈時不靈的情況

?=========================================================================

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

給大家來一個數(shù)據(jù)透視表的簡單版:

PivotSourceRange = ws.Range("M1:O10") #數(shù)據(jù)源 PivotTargetRange = ws.Range("R2") #存放位置PivotCache = wb.PivotCaches().Create(SourceType=1, \ SourceData=PivotSourceRange, Version=5) #這里的version需要注意,不同版本的excel可能version會有偏差PivotTable = PivotCache.CreatePivotTable(\ TableDestination=PivotTargetRange,TableName=PivotTableName) PivotTable.PivotFields("不能說的").Orientation = 1 #行篩選 PivotTable.PivotFields("我好想你").Orientation = 4 #求和項值

?=========================================================================

復(fù)制粘貼,快速下拉

在我剛開始使用win32com的時候,時常會遇到要先將數(shù)據(jù)源篩選再拿取的情況,我一開始的想法是,先篩選再全部吃,但是這種方法,不論你使用win32com還是xlrd讀取數(shù)據(jù),你獲得的最大行列都是不受篩選影響的。后來我想到了不進(jìn)行? ?AutoFilter? 篩選,而是在我吃數(shù)據(jù)的時候添加篩選條件,但是這樣如果條件多的話,寫出來會很冗雜很不美觀,(ps:雖然長名稱確實易于理解,但是放在長代碼里卻會看的人眼花繚亂)

ws.AutoFilterMode=False #取消這個表的所有篩選 ws.Range('A1:Q1').AutoFilter(7,'精英干員') #在你選定的范圍中是第幾列 ws.Range('A1:Q1').AutoFilter(6,'*龍門*') ws.Range('A1:Q1').AutoFilter(5,'人外娘') ============================================ list1=[] for i in (0,nrows):if ws.Range('E%d'%i).Value=='人外娘' and ws.Range('F%d'%i).Value=='龍門' and ws.Range('G%d'%i).Value=='精英干員':list1.append(ws.Range('A%d:Q%d'%(i,i)).Value)

再后來我發(fā)現(xiàn)了復(fù)制粘貼的方法,雖然與一開始一樣,獲得的最大行是篩選前的,但是被篩選隱藏的部分卻不會被選中,這樣一來我就能讓我的代碼更加的簡潔,在寫入的時候也不用再一行行的寫入,運行時間得到了極大的提升。

ws.Range('A1:Q1').AutoFilter(7,'精英干員') ws.Range('A1:Q1').AutoFilter(6,'龍門') ws.Range('A1:Q1').AutoFilter(5,'人外娘')wb.Worksheets.Add().Name='銅雀臺' ws1=wb.Worksheets('銅雀臺')ws.Range('A1:Q%d'%nrows).Copy(ws1.Range('A1')) #同理Cut則是剪切# ws1.Range('K1').Copy() # ws1.Range('K14').PasteSpecial(-4163) #值粘貼

這樣一來,我就將8行的代碼直接縮短了一半

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

excel的使用總不會是單純的復(fù)制粘貼,我們經(jīng)常需要將數(shù)據(jù)進(jìn)行一些加工處理

比如最經(jīng)典的成績單

不論數(shù)據(jù)的多少,我們總是習(xí)慣使用公式,包括但不僅限于excel的函數(shù),在我最開始使用win32com的時候,我使用的是這種方法:

for i in range(0,nrows):ws.Range('H%d'%i).Value='=F%d+G%d'%(i,i)

?但很快我就發(fā)現(xiàn)了這種方法的局限性,平時玩玩還可以,但要是放到大文件中,它寫入的速度就實在是太慢了,excel的處理經(jīng)常一個表就會有上千近萬條,像這樣一個一個格子得寫到什么時候啊

于是我又發(fā)現(xiàn)了這種方法

ws.Range('H2').Value='=F2+G2' ws.Range('H2').AutoFill(ws.Range('H2:H%d'%nrows))

我只需要聲明一次我要的方法,后面的格子就會自動調(diào)用

使用這兩種方法,我原來運行一次要六分鐘的代碼,現(xiàn)在只需要幾十秒就能解決。

?
小貼士

?最后的最后,給大家一個溫馨的提示

因為win32com部分內(nèi)容是VBA與差不多的,所以可能大家會感到困惑。

這種時候我們只需要打開excel的視圖,點擊錄制宏,錄制下我們想進(jìn)行的操作,

然后再查看宏,就能看到這些操作的VBA代碼啦

總結(jié)

以上是生活随笔為你收集整理的win32com 操作excel的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。