Python操作Excel

緣由
sql統(tǒng)計(jì)查詢,然后匯總成excel。因?yàn)槲冶容^懶,老想走捷徑,喜歡折騰,同時(shí)也想著能不能通過python做點(diǎn)啥,正好這個(gè)假期又從頭學(xué)了一次python,所以就想實(shí)踐下。python使用Oracle數(shù)據(jù)庫的資料,發(fā)現(xiàn)很簡單,然后開始嘗試配置環(huán)境,安裝庫文件,折騰了好久,終于一切都順利了,然后又去查了執(zhí)行sql、獲取結(jié)果集,一切都是很順其自然的發(fā)生。然后我又有了新的想法,我在床上查詢了python操作Excel的相關(guān)資料,緊接著今天起床后開始實(shí)踐、實(shí)驗(yàn)、查資料,最后完美達(dá)到結(jié)果,當(dāng)然最大的守護(hù)是對python有了新的認(rèn)知和理解,我能深切體會到她會在以后的工作和生活中,成為我的有一個(gè)新的得力助手,讓我前進(jìn),這簡直完美,也讓人覺得內(nèi)心愉悅。python老是沒堅(jiān)持學(xué)完,沒有什么結(jié)果,主要是沒搞清楚,沒用明白,當(dāng)然也是因?yàn)闆]有真正實(shí)踐去做項(xiàng)目,經(jīng)常練的都是一些基本的簡單操作。今天之前,準(zhǔn)確的說應(yīng)該是搞這個(gè)項(xiàng)目之前,我對python都是偏見的,最不喜歡的就是他的縮進(jìn),但是通過此次項(xiàng)目,我明顯感覺到自己對python有了新的認(rèn)知和見解,忽然覺得豁然開朗了,這種感覺很神奇,就像頓悟一樣。和當(dāng)時(shí)學(xué)java的時(shí)候很像,前前后后自學(xué)了很多,但一直是從自學(xué)到放棄,一直在門外徘徊,直達(dá)后來,我試著去多寫,多實(shí)驗(yàn),多琢磨,盡可能把課后的代碼示例都敲一遍,時(shí)間久了,忽然有一天就和今天的感覺一樣,我覺得自己入門了。準(zhǔn)備工作
安裝openpyxl
pip安裝
pip install openpyxl離線安裝
下載網(wǎng)址:
https://www.lfd.uci.edu/~gohlke/pythonlibs/下載如下文件:
et_xmlfile-1.0.1-py2.py3-none-any.whljdcal-1.4-py2.py3-none-any.whlopenpyxl-2.6.0-py2.py3-none-any.whl
將上述三個(gè)文件拷貝到python安裝目錄中的scripts文件夾下,并通過以下方式安裝:
pip install 文件名完成以上工作,我們就可以開始寫腳本了
引入包資源
from openpyxl import Workbook??或者import openpyxl
兩種方式的區(qū)別就是,下面的這種方式需要在調(diào)用方法的時(shí)候加上openpyxl.,后面還會提到
創(chuàng)建工作表
如果是第一種引包的方式,寫法是這樣的:
# 創(chuàng)建一個(gè)Workbook對象wb = Workbook()
如果是第二種則是這樣的:
wb = openpyxl.Workbook()后面就不再說明了,默認(rèn)用第一種方式
操作sheet
創(chuàng)建sheet
# 創(chuàng)建一個(gè)Sheet對象ws1 = wb.create_sheet(index=0, title="Mysheet")或者ws2 = wb.create_sheet("Mysheet", 0)或者ws3 = wb.create_sheet("Mysheet")
index指的是sheet的位置,0表示第一個(gè),如果省略的話,默認(rèn)是在已有的sheet后面進(jìn)行追加title就是sheet的名字
注意:需要注意的是sheet的名字如果是中文的話,必須是Unicode編碼
ws2.title = (u"你好") #設(shè)定一個(gè)sheet的名字 必須是Unicode獲取sheet
獲取活動的sheet
# 獲取活動的sheetactiveSheet = wb.active
根據(jù)名字獲取sheet
#獲取某個(gè)sheet對象print (wb.get_sheet_by_name(u"你好" ))
獲取所有sheet
#獲取全部sheet 的名字,遍歷sheet名字print (wb.sheetnames)for sheet_name in wb.sheetnames:print (sheet_name)# 遍歷wb中的sheetfor sheet in wb:print (sheet.title)
編輯sheet標(biāo)簽背景顏色
# 設(shè)置活動表顏色activeSheet.sheet_properties.tabColor = "205EB2"#設(shè)定sheet的標(biāo)簽的背景顏色ws1.sheet_properties.tabColor = "1072BA"
復(fù)制sheet
# 復(fù)制一個(gè)sheetwb["New Title" ]["A1"]="zeke"source = wb["New Title" ]target = wb.copy_worksheet(source)
單元格操作
讀取數(shù)據(jù)
print(mySheet['B4'].value)賦值
下面這幾種操作方式,本質(zhì)上一樣
mySheet['B4'].value = 'hello world'或者wb["New Title" ]["A1"]="zeke"或者tableNameCell = activeSheet.cell(row = 1, column = 1, value = 'hello')
單元格合并
mySheet.merge_cells('a1:d1')上面的操作就是合并a1到d1之間的單元格
設(shè)置行高
mySheet.row_dimensions[1].height = 55設(shè)置列寬
# 設(shè)置列寬度mySheet.column_dimensions['A'].width = 36
單元格求和
sum = 0for cellssss in mySheet['B4:B20']:for cell in cellssss:co = cell.valueif not co is None:sum = sum + cell.valueprint("求和結(jié)果:", sum)
這里我寫了一個(gè)方法,用于單元格求和:
# 求和# cells 取值為sheet的切片,如:mySheet['B4:B20']def sum(cells):sum = 0for cellssss in cells:for cell in cellssss:co = cell.valueif not co is None:sum = sum + cell.valueprint("求和結(jié)果:", sum)return sum
批量操作單元格
比如操作A3-D3,A7-D7,A14-D14,A18-D18這些區(qū)域的單元格,我的解決方法如下:
# 背景填充for i in [3, 7, 10, 14, 18]:for cells in mySheet['A'+ str(i) +':D' + str(i)]:for cell in cells:cell.fill = fill
如果是操作某一范圍內(nèi)的單元格,這樣這樣操作,其實(shí)上面求和就是這么操作的:
for cells in mySheet['D3:D21']:for cell in cells:valueC = mySheet['C' + str(cell.row)].valuevalueB = mySheet['B' + str(cell.row)].value# 或者這樣# 獲取單元格切片cellsA = mySheet['B3:D21']# 設(shè)置表格樣式for cellssss in cellsA:for cell in cellssss:cell.style = dataCellStyle
上面的操作其實(shí)大同小異,基本上都一樣。需要提到的是
cell.row獲取到的是單元格的行號,比如A20,獲取到的是20cell.column_letter獲取到的是單元格的列,即字母,比如B20獲取到的是Bcell.col_idex獲取到的是當(dāng)前單元格列字母對應(yīng)的序號,比如A2對應(yīng)的是1,E3對應(yīng)的是5,Z4對應(yīng)的是26,AA4對應(yīng)的是27,以此類推
單元格樣式操作
引入包
from openpyxl.styles import colorsfrom openpyxl.styles import NamedStyle,Alignment,Side,Border,Font,Color,PatternFill
NamedStyle是其他所有樣式的載體;Alignment是文本對齊樣式(垂直/水平);Side是邊框樣式,線條寬度,顏色,線條虛實(shí)等;Border是單元格邊框樣式,上、下、左、右等;Font是字體樣式,包括字體、大小、顏色等;PatternFill是填充樣式,包括填充顏色、填充樣式等創(chuàng)建樣式
指定樣式名稱,創(chuàng)建樣式
classopenpyxl.styles.named_styles.NamedStyle(name='Normal',font=Parameters: name=None, charset=None, family=None, b=False, i=False,strike=None, outline=None, shadow=None, condense=None,color=None, extend=None, sz=None, u=None, vertAlign=None,scheme=None, fill=Parameters: patternType=None,fgColor=Parameters: rgb='00000000', indexed=None, auto=None,theme=None, tint=0.0, type='rgb',bgColor=Parameters: rgb='00000000', indexed=None, auto=None,theme=None, tint=0.0, type='rgb',border=Parameters: outline=True, diagonalUp=False,diagonalDown=False, start=None, end=None,left=Parameters: style=None, color=None,right=Parameters: style=None, color=None,top=Parameters: style=None, color=None,bottom=Parameters: style=None, color=None,diagonal=Parameters: style=None, color=None, vertical=None,horizontal=None,alignment=Parameters: horizontal=None, vertical=None, textRotation=0,wrapText=None, shrinkToFit=None, indent=0.0, relativeIndent=0.0,justifyLastLine=None, readingOrder=0.0, number_format=None,protection=Parameters: locked=True, hidden=False, builtinId=None,hidden=False, xfId=None)
示例:
headerCellStyle = NamedStyle(name = 'headerCellStyle')創(chuàng)建文本對齊樣式
classopenpyxl.styles.alignment.Alignment(horizontal=None,vertical=None, textRotation=0, wrapText=None, shrinkToFit=None,indent=0, relativeIndent=0, justifyLastLine=None, readingOrder=0,text_rotation=None, wrap_text=None, shrink_to_fit=None,mergeCell=None)
示例:
# 水平垂直居中headerCellStyle.alignment = Alignment(horizontal = 'center',vertical = 'center')
horizontal表示水平對齊方式,vertical表示垂直對齊方式,取值有center、left、right
創(chuàng)建線框樣式
這個(gè)樣式是給單元格樣式準(zhǔn)備的,不是直接賦給headerCellStyle的,它的歸屬關(guān)系是:openpyxl.styles.borders.Side
classopenpyxl.styles.borders.Side(style=None, color=None,border_style=None)
示例:
# 線框樣式border = Side(border_style = 'thin', color = '000000')
border_style取值范圍如下:
'slantDashDot','medium','hair','mediumDashDotDot','dashed','dotted','thick','double','dashDotDot','thin','mediumDashDot','mediumDashed','dashDot'
color取值是十六進(jìn)制顏色
創(chuàng)建單元格邊框樣式
設(shè)置單元格上下左右的邊框樣式,包信息:openpyxl.styles.borders.Border
classopenpyxl.styles.borders.Border(left=?Parameters:? style=None,?color=None,?right=?Parameters:? style=None,?color=None,?top=?Parameters:? style=None,?color=None,?bottom=? Parameters:?style=None,?color=None,?diagonal=? Parameters:?style=None,?color=None,?diagonal_direction=None,?vertical=None,?horizontal=None,?diagonalUp=False,?diagonalDown=False,?outline=True,?start=None,?end=None)
示例:
# 設(shè)置單元格邊框樣式headerCellStyle.border = Border(left = border,top = border, right = border, bottom = border)
left,right,top,bottom的取值,來源于我們前面定義的線框樣式(Side)
創(chuàng)建字體樣式
classopenpyxl.styles.fonts.Font(name=None,sz=None, b=None, i=None, charset=None,u=None, strike=None, color=None, scheme=None,family=None, size=None, bold=None, italic=None,strikethrough=None, underline=None, vertAlign=None,outline=None, shadow=None, condense=None, extend=None)
示例:
# 大標(biāo)題字體nameFont = Font(name = '等線',size = 16,bold = True,italic = False,vertAlign = None,underline = 'none',strike = False)
字體的相關(guān)屬性都很簡單,vertAlign是水平對齊,strike表示刪除線
創(chuàng)建填充樣式
classopenpyxl.styles.fills.PatternFill(patternType=None,fgColor=Parameters: rgb='00000000', indexed=None, auto=None,theme=None, tint=0.0, type='rgb',bgColor=Parameters: rgb='00000000', indexed=None, auto=None,theme=None, tint=0.0, type='rgb', fill_type=None,start_color=None, end_color=None)
示例:
fill = PatternFill("solid", fgColor="E2EFDA")注意:以上樣式都可以通過如下方式直接賦值給單元格,比如:
cell.fill = fillcell.font = normalfont
如果是單個(gè)樣式,通過如上方式直接賦值給單元格即可,如果樣式比較多,我個(gè)人覺得通過創(chuàng)建NamedStyle的方式比較合理。
tableNameCell.style = tableNameStyle其他樣式目前沒有用到,這里不介紹了,有需要的小伙伴可以去看文檔:http://yumos.gitee.io/openpyxl3.0/index.html#document-styles
這里放一個(gè)比較完整的樣式:
# 字體樣式normalfont = Font(name = '等線',size = 11,italic = False,vertAlign = None,underline = 'none',strike = False)# 填充樣式fill = PatternFill("solid", fgColor="E2EFDA")# 創(chuàng)建單元格樣式對象headerCellStyle = NamedStyle(name = 'headerCellStyle')# 水平垂直居中headerCellStyle.alignment = Alignment(horizontal = 'center', vertical = 'center')# 線框樣式border = Side(border_style = 'thin', color = '000000')# 設(shè)置單元格邊框樣式headerCellStyle.border = Border(left = border, top = border, right = border, bottom = border)headerCellStyle.font = normalfont# 填充樣式titleStyle.fill = fill
保存數(shù)據(jù)
# 保存數(shù)據(jù)
wb.save("python-first-excel.xlsx")
# 關(guān)閉工作表
wb.close()好了,本次探討到這里就結(jié)束了,如果你能掌握以上內(nèi)容,你已經(jīng)可以可以通過python創(chuàng)建一個(gè)excel文件,然后填充你的數(shù)據(jù),美化調(diào)整單元格的樣式。如果你配合我前一篇博客,已經(jīng)已經(jīng)可以生成簡單的excel報(bào)表了,當(dāng)然,這里只是簡單演示了openpyxl操作單元格的基本方法,其實(shí)還有很多強(qiáng)大的功能沒有展示,比如excel的各種圖表的繪制等,一方面是由于篇幅的原因,另外一方面我還沒想好,但主要還是因?yàn)槲疫€沒學(xué)??
