在Django中有时候需要在后台界面需要用到导出数据的功能,对于功能要求比较高的可以直接使用Import_Export库来完成。但是对于一些简单的数据导出,可以直接自定义一些简单的函数来实现导出数据。
经过测试,有以下两种方法可以使用:HttpResponse 和 FileResponse 两种方法。
首先引入 from django.http import HttpResponse
添加导出动作:
actions = ['export_excel']
# 导出数据到EXCEL文件
def export_excel(self, request, queryset):
meta = self.model._meta
# field_names = [field.name for field in meta.fields]
# 如果直接按照数据库字段进行导出,直接使用上面的代码,如果需要进行部分字段的筛选,同时为导出的文件添加中文表头,可以使用下面的代码
cn_name = ['区域', 'A库存数','A库存金额', 'B库存数', 'B库存金额', 'C库存数', 'C库存金额', '库存日期', '备注信息']
field_names = ['quyu', 'Akcs', 'Akcj', 'Bkcs', 'Bkcj', 'Ckcs','Ckcj','kc_date', 'note']
today_time = time.strftime('%Y%m%d%H%M%S', time.localtime())
filename = f'{str(meta)[7:]}' + '_' + f'{today_time}'
response = HttpResponse(content_type='application/msexcel')
response['Content-Disposition'] = f'attachment; filename={filename}.xlsx'
wb = Workbook()
ws = wb.active
# ws.append(field_names)
ws.append(cn_name) # 写入中文表头
for obj in queryset:
for field in field_names:
data = [f'{getattr(obj, field)}' for field in field_names]
row = ws.append(data)
wb.save(response)
self.message_user(request, f"{request.user.username}导出库存数据<{filename}.xlsx>")
return response
export_excel.short_description = '下载数据'
export_excel.type = 'info'
export_excel.confirm = '确认即将开始导出差异数据!'
1、field_names = [field.name for field in meta.fields];
field_names 如果使用这个代码,是直接使用的数据库的全部字段;
field_names = [ ] 这个是在全部字段的基础上进行的筛选,只保留部分需要导出的字段,可以减小导出数据的体积;
2、表头的写入:
ws.append(field_names) —— 这行代码值直接写入数据库字段定义的名称作为表头;虽然非中文不利于阅读,但是这种方式生成的文件适合作为数据库导入数据时的模板;
ws.append(cn_name) # 写入中文表头,方便阅读;但不适合作为数据导入模板;
3、filename的定义:
在定义filename的时候,加入了today_time的定义,而且将today_time定义到'%Y%m%d%H%M%S',是方便区分文件,便面固定文件名称在第二次导出的时候造成文件覆盖;同时还可以作为时间戳标记;
首先导入:from django.http import FileResponse
添加动作:actions = ['export_excel','export_csv']
def export_csv(self, request, queryset):
today_time = time.strftime('%Y%m%d%H%M%S', time.localtime())
filename = '/logs/' + 'myform_' + f'{today_time}.csv'
ids = list(queryset.values_list('quyu', 'wxkcs', 'wxkcj', 'dlkcs', 'dlkcj', 'zykcs','zykcj','note'))
print(ids,type(ids))
biaotou = '区域,A库存数,A库存金额,B库存数,B库存金额,C数量,C金额,备注\n'
with open(filename, 'a+') as f:
f.write(biaotou)
for i in ids:
f.write(str(i)[1:-3]+'\n')
newname = f'kucun' + '_' + f'{today_time}.csv'
response = FileResponse(open(filename, "rb"))
response['Content-Type'] = 'application/octet-stream'
response['Content-Disposition'] = f'attachment; filename={newname}'
self.message_user(request, f"{request.user.username}导出库存数据<{newname}")
return response
export_csv.short_description = '下载数据CSV'
export_csv.type = 'info'
export_csv.confirm = '确认即将开始导出差异数据!'
相关说明:
1、导出文件的格式:
格式并不固定,可以是csv\txt\log等多种格式,这里选择csv是因为处理数据比较方便;
2、为什么非要保存为一个独立的文件?
这个地方原本是另外一个很复杂的函数,通过数据整合成为有固定格式的word文档,当然也可以是PDF文档;然后下载的是一个格式排版都比较精美的文档;为了简化代码,使主函数功能更清晰,这里就使用csv文件做简单的说明;
3、表头的汉字说明:
为了能使导出的数据更清晰,便于阅读,特意添加了一行中文的表头;
其他的内容都比较简单、清晰,可以结合第一种方法看一下。
这两种方法都可以实现简单的数据导出、下载功能;各有一定的作用。也可以在下载的同时,将文件同时保存在服务器以便备查;配合一些日志记录。