之前我做的一個Django項目需要導出excel表格,具體場景描述:數據庫中有用戶表,商品表,訂單表等等數據表,每張數據表都有多個字段,而客戶不需要導出所有字段,只需要導出每張表部分字段。基於這樣的場景,我不可能每一張數據表的excel導出都單獨寫一個方法,因此我嘗試寫了一個excel導出的封裝類,每次需要導出excel時,只需要傳入指定參數創建一個對象,然後調用該對象的work_on方法即可實現excel表導出,導出方式是在瀏覽器端實現下載,主要呈現形式在瀏覽器端下載列表可以看到,就像我們平時在瀏覽器下載一個文件似的,這樣就實現了不同的數據表都可以調用相同的一個模塊來實現導出,實現了模塊的複用。這樣客戶在瀏覽器端點擊導出選項後就會在瀏覽器端自動下載導出的excel表格了。
class SuperExportExcel:
"""數據庫導出excel模塊"""
def __init__(self, header, fields, data, filename):
# header: excel表的字段名(excel表的第一行)
# fields: 對應的數據庫的字段名
# data: 序列化後的數據(這裏主要是針對QuerySet序列化後的數據)
# filename: 導出的excel文件名
self.header = header
self.fields = fields
self.data = data
self.filename = filename
self.output = io.BytesIO()
self.workbook = xlsxwriter.Workbook(self.output)
self.count = 0
self.n = len(self.data)
# 創建一個excel表
def create_worksheet(self):
worksheet = self.workbook.add_worksheet('第' + str(self.count + 1) + '頁')
for i in range(len(self.header)):
worksheet.write(0, i, self.header[i])
self.count += 1
return worksheet
# 向表中寫數據
def write_info(self, worksheet, data):
for i in range(len(data)):
for j in range(len(self.fields)):
worksheet.write(i + 1, j, data[i][self.fields[j]])
# 執行下載操作
def worksheet_download(self):
xlsx_data = self.output.getvalue()
response = HttpResponse(content_type='application/ms-excel')
# print(self.filename)
response['Content-Disposition'] = \
"attachment; filename*=utf-8''{}".format(escape_uri_path(self.filename + '.xlsx'))
response.write(xlsx_data)
return response
# 工作函數
def work_on(self):
while True:
worksheet = self.create_worksheet()
self.write_info(worksheet, self.data[(self.count - 1) * 60000:self.count * 60000])
self.n -= 60000
if self.n <= 0:
break
self.workbook.close()
res = self.worksheet_download()
return res