封裝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)
