【Python3】xlwt/xlrd模組讀取和新建excel並生成直方圖
此文轉載自:https://blog.csdn.net/weixin_52855865/article/details/110109460#commentBox
Python-Excel處理
這是一個關於測試報告(Excel)的總結與繪製直方圖的指令碼。指令碼的功能是實現對測試報告中多個工作頁(sheet)提取P/Fp/F的單元格(cell),並分別統計數量,再據此繪製直方圖。
一、模組的安裝
我們需要用到以下幾個模組:
1.pip:該工具包提供了對Python包的查詢、下載、安裝、解除安裝功能。
2.xlrd:讀取excel
3.xlwt:寫入excel
4.matplotlib:Python的2D繪相簿
pip官網:https://pypi.org/project/pip/
為了下載pip.py先安裝wget:
yum -y install wget
下載pip安裝檔案並安裝:
wget https://bootstrap.pypa.io/get-pip.py
python get-pip.py
安裝驅動(ddt)、xlrd和xlwt:
pip install ddt
pip install xlrd
pip install xlwt
安裝matplotlib:
sudo apt-get install python3-matplotlib
二、讀取Excel——xlrd
首先,我們需要理解Excel檔案的三層級物件:workbook、sheet、cell。
即:
workbook = xlrd.*
sheet = workbook.*
cell = sheet.cell*
1.xlrd基礎介面用法
xlrd各介面用法:
(1) 開啟檔案
workbook = xlrd.open_workbook('123.xlsx')
(2) 獲取檔案中包含的所有工作表名稱
sheets = workbook.sheet_names()
(3) 選定工作表
sheet = workbook.sheets()[0] #通過索引獲取
sheet = workbook.sheet_by_index(0) #通過順序獲取
sheet = workbook.sheet_by_name('sheet1') #通過表名獲取
(4) 獲取行數和列數
nrows = sheet.nrows
ncols = sheet.ncols
(5) 列印“表名”“行數”“列數”
print(sheet.name,sheet.nrows,sheet.ncols)
(6) 獲取全表資料
for i in range(1,nrows+1): #對於行,從第一行讀取到總行數
for j in range(1,ncols+1): #對於列,從第一列讀取到總列數
data = sheet.cell(i-1,j-1).value
Tips1:
for i in range(1,n)
i 的取值為1,2,3……n-1。
當然也可以寫成:
for i in range(0,nrows):
for j in range(0,ncols):
data = sheet.cell(i,j).value
但我個人更傾向於第一種,因為第一種寫法的意義更明確。
Tips2:對於工作表的第一行第一列
data = sheet.cell(0,0).value
Tips3:value表示“值”,是否加value決定輸出格式。
data = sheet.cell(1,2).value
輸出如下:
--------------------------------------------------------------------------
data = sheet.cell(1,2)
輸出如下:
2.迴圈讀取sheet
程式碼如下:
workbook = xlrd.open_workbook(fname)
sheets = workbook.sheet_names() #獲取所有工作表名稱並形成陣列
nsheets = len(sheets) #得出陣列長度
for z in range(1,nsheets+1):
sheet = workbook.sheet_by_index(z-1)
3.在sheet中定位關鍵字
程式碼如下:
global rowst #定義為全域性變數方便其他函式呼叫
global colst #定義為全域性變數方便其他函式呼叫
for i in range(1,nrows+1):
for j in range(1,ncols+1):
data1 = sheet.cell(i-1,j-1).value
if (data1=='P')or(data1=='Fp')or(data1=='F'):
rowst = i
colst = j
#得到關鍵字所在單元格座標(i,j)
Tips1:
if (data1==‘P’) or (data1==‘Fp’) or (data1==‘F’):
不能寫成:
if data1 == (‘P’ or ‘Fp’ or ‘F’):
4.在sheet中確定首位關鍵字
在上面的程式碼中獲得的包含關鍵字的單元格有很多個,那麼如何確定滿足條件(所在行列全為P/Fp/F)的首位關鍵字呢?
我們需要以下兩步:
① 判斷是否滿足條件
② 一旦滿足條件立刻退出迴圈
程式碼如下:
count_l = 0
count_col = 0
for l in range(colst,ncols+1):
data_l = sheet.cell(rowst-1,l-1).value #讀取關鍵字所在行的資料
if data_l != "": #如果單元格內容不為空
count_col+=1 #自加一,統計有資料的單元格個數
if (data_l=='P') or (data_l=='Fp') or (data_l=='F'):
count_l+=1 #自加一,統計含有關鍵字的單元格個數
if count_l == count_col: #如果兩者的數量相等,則可以確定該關鍵字所在行全為P/Fp/F
#繼續判斷列是否滿足條件
count_w = 0
count_row = 0
for w in range(rowst,nrows+1):
data_w = sheet.cell(w-1,colst-1).value #讀取關鍵字所在列的資料
if data_w != "": #如果單元格內容不為空
count_row+=1 #自加一,統計有資料的單元格個數
if (data_w=='P' or data_w=='Fp' or data_w=='F'):
count_w+=1 #自加一,統計含有關鍵字的單元格個數
if count_w == count_row: #如果兩者的數量相等,則可以確定該關鍵字所在列全為P/Fp/F
print (rowst,end=',')
print (colst)
return #確定首位滿足條件的單元格即退出迴圈
Tips1:
if data_l == "":
""表示單元格資料為空,有框線無內容也為空。
如果寫成
if data_l == None:
None也表示單元格內容為空,但是有框線無內容不判定為空。
Tips2:
count_l+=1
表示變數自加一,也可以寫成:
count_l = count_l +1
Tips3:
print (rowst,end=’,’)
print (colst)
end=’'表示輸出結果不換行顯示,‘,’表示用逗號隔開,則輸出結果表示為(rowst,colst)。
5. 統計資料並將結果儲存為陣列
程式碼如下:
global count_P
global count_Fp
global count_F
count_P = 0
count_Fp = 0
count_F = 0
list = [] #建立一個空陣列列表
for m in range(rowst,nrowst+1):
for n in range(colst,ncols+1):
data2 = sheet.cell(m-1,n-1).value
if data2 == 'P':
count_P+=1 #統計P的數量
elif data2 == 'Fp':
count_Fp+=1 #統計Fp的數量
elif data2 == 'F':
count_F+=1 #統計F的數量
total = count_P + count_Fp + count_F
list.append(count_P)
list.append(count_Fp)
list.append(count_F)
list.append(total)
print (list)
Tips1:append()函式用於在列表末尾新增新的物件。
Tips2:將結果儲存成陣列是為了方便後續將資料寫入新的Excel。
三、寫入新Excel——xlwt
1.目的表格
欲獲得的表格如下:
Bug Summary | ||||
---|---|---|---|---|
– | sheet1 | sheet2 | …… | sheet n |
P | ||||
Fp | ||||
F | ||||
Total |
2.建立新Excel並寫入資料
程式碼如下:
workbook = xlwt.Workbook() #建立空白工作表,注意W大寫
worksheet = workbook.add_sheet('sheet1') #建立空白工作頁並命名
worksheet.write_merge(0,0,0,nsheets,"Bug Summary",style) #寫入表頭併合並第一行單元格
i=1
for sheet in sheets: #對陣列sheets中的資料掃描
worksheet.write(1,i,sheet,style) #從第二行第二列開始將資料寫入第二行
i+=1
worksheet.write(2,0,'P',style)
worksheet.write(3,0,'Fp',style)
worksheet.write(4,0,'F',style)
worksheet.write(5,0,'Total',style)
list1 = list[::4] #從第一位到最後一位,每隔4位取一個值組成新的陣列,則list1為所有工作頁中P的數量的陣列
list2 = list[1::4] #從第二位到最後一位,每隔4位取一個值組成新的陣列,則list2為所有工作頁中Fp的數量的陣列
list3 = list[2::4] #從第三位到最後一位,每隔4位取一個值組成新的陣列,則list3為所有工作頁中F的數量的陣列
list = list[3::4] #從第四位到最後一位,每隔4位取一個值組成新的陣列,則list4為所有工作頁中Total總數的陣列
#寫入資料
j=1
for num in list1:
worksheet.write(2,j,num,style) #在第三行寫入list1
j+=1
j=1
for num in list2:
worksheet.write(3,j,num,style) #在第四行寫入list2
j+=1
j=1
for num in list3:
worksheet.write(4,j,num,style) #在第五行寫入list3
j+=1
j=1
for num in list4:
worksheet.write(5,j,num,style) #在第六行寫入list4
j+=1
workbook.save('111.xlsx') #儲存為111.xlsx
print ("Done") #輸出已完成
Tips1:對於一行資料的陣列,寫入excel時只能按行寫入,所以本程式碼中將陣列進行拆分,按行寫入。
Tips2:
worksheet.write(i,j,num,style)
如果未定義格式,則style可省略,按預設格式錄入。
需要注意的是,帶格式寫入只有以上一種寫法,以下寫法是錯誤的:
worksheet.write(0,0,label=“Bug Summary”,style)
而對於不帶格式寫入,以下兩種寫法都是正確的:
worksheet.write(0,0,label=“Bug Summary”)
worksheet.write(0,0,“Bug Summary”)
Tips3:注意 j+=1,不然會報錯重複寫入。
Tips4:
for num in list
num不需要定義,表示對陣列內容按位讀取。
3.自定義表格樣式
先定義一個空style,再定義字型、邊框。
這是一個設定好格式但允許改變顏色的style,程式碼如下:
① 新建一個style
def set_color(color):
#新建一個style
style = xlwt.XFStyle()
② 設定字型樣式
font = xlwt.Font() #新建一個字型樣式
font.name = 'Arial' #字型
font.bold = True #黑體加粗
font.colour_index = color #允許自定義顏色,注意介面中的拼寫為colour
font.underline = True #下劃線
font.italic = True #斜體
style.font = font
③ 設定邊框
borders = xlwt.Borders() #新建一個邊框樣式
borders.left = xlwt.Borders.THIN #設定左邊框為實線
borders.right = xlwt.Borders.THIN
borders.top = xlwt.Borders.THIN
borders.bottom = xlwt.Borders.THIN
style.borders = borders
Tips: 其他樣式
borders.top = xlwt.Borders.DASHED #虛線
borders.top = xlwt.Borders.NO_LINE #無框線
④ 設定對齊方式
alignment = xlwt.Alignment() #新建一個對齊模板
alignment.horz = xlwt.Alignment.HORZ_CENTER #水平方向居中對齊
#alignment.horz = xlwt.Alignment.HORZ_LEFT 左對齊
#alignment.horz = xlwt.Alignment.HORZ_RIGHT 右對齊
alignment.vert = xlwt.alignment.VERT_CENTER
#alignment.vert = xlwt.Alignment.VERT_TOP 上對齊
#alignment.vert = xlwt.Alignmnet.VERT_BOTTOM 下對齊
style.alignment = alignment
Tips:其他對齊
#alignment.horz = xlwt.Alignment.HORZ_GENERAL 預設對齊
--------------------------------------------------------------------------
#alignment.horz = xlwt.Alignment.HORZ_FILLED 填滿對齊
--------------------------------------------------------------------------
#alignment.horz = xlwt.Alignment.HORZ_DISTRIBUTED 分散式對齊
⑤ 設定背景色
pattern = xlwt.Pattern()
pattern.pattern = xlwt.Pattern.SOLID_PATTERN #實填充
pattern.pattern_fore_color = 4 #填充為藍色
style.pattern = pattern
下圖是顏色對照表:
⑥ 設定完成
設定完成後記得:
return style
四、繪製直方圖
繪製直方圖需要用到以下幾個模組
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
1.在直方圖上標註資料
先定義一個在直方圖上標註資料的函式
def autolabel(rects):
for rect in rects:
height = rect.get_height() #獲取高度
plt.text(rect.get_x() + rect.get_width()/2,height,height) #標註點的位置為(x的座標+直方的寬度)/2 取中
2.繪製直方圖
程式碼如下:
df = pd.read_excel('111.xlsx','sheet1') #讀取111.xlsx的sheet1工作頁
fig = plt.figure()
x = np.arange(1,nsheets) #定義橫座標x的取值陣列,必須為陣列
list1 = list[::4]
list2 = list[1::4]
list3 = list[2::4] #在其他函式裡需要再取一遍
t0 = plt.bar(x,list1,width=0.3,label='P',fc='b') #畫出P的直方圖,表示為藍色
t1 = plt.bar(x+0.3,list2,width=0.3,label='Fp',fc='r') #畫出Fp的直方圖,表示為紅色
t2 = plt.bar(x+0.6,list3,width=0.3,label='F',fc='g') #畫出F的直方圖,表示為綠色
autolabel(t0)
autolabel(t1)
autolabel(t2) #用autolabel函式進行標註
plt.legend(['P','Fp','F']) #繪製右上角的註釋圖
plt.xlabel('case') #設定橫軸
plt.ylabel('amount') #設定縱軸
plt.title('summary') #設定標題
plt.show() #繪製圖象
繪製的直方圖如下:
五、其他
以下這篇文章對糾錯很有幫助:python操作excel中遇到的錯誤
希望這篇文章對正在學習的你也有幫助,如有疑問歡迎留言o(≧v≦)o~~