之前我做的一个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