封裝Excel工具類
我們常用的excel工具類,讀有xlrd,寫有xlwt。有讀有寫,新一代庫有pandas,openpyxl等等。
大家用法都差不多,今天博主就介紹新手最愛,我也愛的xlrd
和xlwt
。(不過xlwt似乎最多隻支援65535條資料,此乃一坑)
緣起
老闆給博主安排了一個匯出excel
的任務,而這個新專案裡面還尚未編寫此類公共方法,於是就想來一波嘗試。
主要是想把xlwt和xlrd做一個整合,但並不是說要對一個檔案讀和寫,因為應用場景一般是匯入
或者匯出
。
封裝ExcelHelper類
讀資料
我們需要先接受一個filename(檔案的全路徑),初始化helper物件,所以我們可以順手寫出這樣的程式碼:
class ExcelHelper(object):
def __init__(self, filename):
self.filename = filename
接著我們編寫xlrd的部分,雖然網上的例子一大把,但是有特色的還是少。我決定支援讀陣列,也支援讀json陣列。
啥子是json陣列,因為我們excel一般都是表頭+表資料組成,如果光給一條資料,你不知道他屬於哪一列
,那還得往上找它的表頭,和之對應起來。
比如我們經常讀出的資料是:
data = [
['姓名', '電話'],
['三毛', '17800000000']
]
當列的資料比較多的時候,我們給你一個三毛
,你知道它的表頭是姓名嗎?還是小名?
如果是這樣的資料呢?
data = [
{"姓名": "三毛", "電話": "17800000000"}
]
兩種資料,不同的展示方式,其實內容相差無幾。
- 編寫read_data方法
def read_data(self):
"""
獲取資料,不區分表頭
:return:
"""
book = xlrd.open_workbook(self.filename)
sheets = book.sheets()
for s in sheets:
yield (s.row_values(i) for i in range(s.nrows))
這邊用了yield關鍵字,之所以不用list,還是考慮到資料表資料如果很多,那麼全部放到list,會佔用很大記憶體空間,所以用了yield節省記憶體空間
。
這裡如果有疑問,大家可以查下生成器
相關資料。
- 編寫read_json相關方法
@staticmethod
def read_json_item(sheet):
"""
獲取json資料
:param sheet:
:return:
"""
if sheet.nrows <= 1:
return (sheet.row_values(i) for i in range(sheet.nrows))
# 否則說明資料大於1行
header = sheet.row_values(0)
for i in range(1, sheet.nrows):
row_data = dict()
for j in range(sheet.ncols):
row_data[header[j]] = sheet.cell_value(i, j)
yield row_data
def read_json_data(self):
"""
獲取List[dict]資料,也就是JSON陣列
:return:
"""
book = xlrd.open_workbook(self.filename)
sheets = book.sheets()
for st in sheets:
yield ExcelHelper.read_json_item(st)
比較常規,excel可能會有多個sheet,所以我們遍歷sheets。接著去每個sheet中拿到每行資料,由於要求json陣列模式,所以我們需要判斷下行數。
如果就1行,那就最多一個表頭,沒啥意義,所以我們直接切換到原生模式,一行一行讀資料。
寫資料
寫資料的demo比較簡單,考慮到傳入json陣列的時候,萬一有小可愛傳這樣的資料,其實我們是不太好支援的:
a = [
{"名字": "張三", "稱號": "法外狂徒"},
{"性格": "悶騷", "稱號": "秒殺光環"}
]
可以看到2條資料對不上~所以不打算支援這樣的資料。
-
編寫write_data方法
我們知道,表頭是個很重要的資料,我們要讓她
與眾不同
一點,所以我們可以設定下它的樣式。
@staticmethod
def get_style():
style = xlwt.XFStyle()
pattern = xlwt.Pattern()
pattern.pattern = xlwt.Pattern.SOLID_PATTERN
pattern.pattern_fore_colour = xlwt.Style.colour_map['sky_blue']
style.pattern = pattern
return style
建立style,設定背景色為純潔的天藍色
,最後返回style。
這個style有什麼用呢,我們在寫入資料的時候可以指定單元格
的樣式。
接著編寫write方法:
def write_excel_data(self, header, row_data, sheet_name="sheet1"):
wb = xlwt.Workbook()
ws = wb.add_sheet(sheet_name)
# 寫入表頭
for i, h in enumerate(header):
ws.write(0, i, h, self.style)
# 寫入資料
for line, row in enumerate(row_data):
for c, item in enumerate(row):
ws.write(line + 1, c, str(item))
wb.save(self.filename)
接受引數是表頭(陣列),row_data(二維陣列),寫入完畢後呼叫save方法。
如果有需要對多個sheet寫入,請自行改造。
本節總體來說,只是寫了一個excel的讀寫方法,亮點在於讀json陣列
和表頭搞顏色
。
下次聊聊FastApi下載檔案以及刪除下載後的檔案。
完整程式碼如下(其實是給我自己備份):
import xlrd
import xlwt
class ExcelHelper(object):
def __init__(self, filename):
self.filename = filename
self.style = ExcelHelper.get_style()
@staticmethod
def get_style():
style = xlwt.XFStyle()
pattern = xlwt.Pattern()
pattern.pattern = xlwt.Pattern.SOLID_PATTERN
pattern.pattern_fore_colour = xlwt.Style.colour_map['sky_blue']
style.pattern = pattern
return style
def read_data(self):
"""
獲取資料,不區分表頭
:return:
"""
book = xlrd.open_workbook(self.filename)
sheets = book.sheets()
for s in sheets:
yield (s.row_values(i) for i in range(s.nrows))
@staticmethod
def read_json_item(sheet):
"""
獲取json資料
:param sheet:
:return:
"""
if sheet.nrows <= 1:
return (sheet.row_values(i) for i in range(sheet.nrows))
# 否則說明資料大於1行
header = sheet.row_values(0)
for i in range(1, sheet.nrows):
row_data = dict()
for j in range(sheet.ncols):
row_data[header[j]] = sheet.cell_value(i, j)
yield row_data
def read_json_data(self):
"""
獲取List[dict]資料,也就是JSON陣列
:return:
"""
book = xlrd.open_workbook(self.filename)
sheets = book.sheets()
for st in sheets:
yield ExcelHelper.read_json_item(st)
def write_excel_data(self, header, row_data, sheet_name="sheet1"):
wb = xlwt.Workbook()
ws = wb.add_sheet(sheet_name)
# 寫入表頭
for i, h in enumerate(header):
ws.write(0, i, h, self.style)
# 寫入資料
for line, row in enumerate(row_data):
for c, item in enumerate(row):
ws.write(line + 1, c, str(item))
wb.save(self.filename)