接口实现mysql数据库的数据读取写入到excel表格
前言:要求网站页面加一个导出按钮,点击后实现数据从mysql写入到excel表格,并且以附件的形式下载
def exportdata(request):
# 定义时间,在下载附件的时候以时间为文件名
time_str = datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
file_name = 'Rule_list' + '_' + time_str + 'result.xlsx'
# 项目路径
document_root = settings.BASE_DIR
dest_filename = document_root + '\\BM\\query_tmp\\' + file_name
wb = xlsxwriter.Workbook(dest_filename)
ws = wb.add_worksheet('Menu')
# 定义写入excel文件的时间格式
format2 = wb.add_format({'num_format': 'yyyy/mm/dd hh:mm:ss'})
format3 = wb.add_format({'align': 'center'})
fomat4 = wb.add_format({'border': 1})
row_num = 0
# 设置表头
columns = ['a', 'b', 'c', 'd', 'time', 'f', 'g', 'h']
for col_num in range(len(columns)):
#表头写入第一行
ws.write(row_num, col_num, columns[col_num])
#从数据库获取指定字段的数据
rows = Gerrit_Reviewer_Rule.objects.values_list('a', 'b', 'c', 'd', 'time', 'f',
'g', 'h')
for row in rows:
row_num += 1
#此时row是元组形式,需转换成列表的形式
row = list(row)
for col_num in range(len(row)):
# ws.write(row_num, col_num, row[col_num])
ws.write(row_num, 0, row[0],format3)
ws.write(row_num, 1, row[1])
ws.write(row_num, 2, row[2])
ws.write(row_num, 3, row[3])
ws.write(row_num, 4, row[4], format2)
ws.write(row_num, 5, row[5])
ws.write(row_num, 6, row[6])
ws.write(row_num, 7, row[7])
wb.close()
# 数据库的数据写入excel表格之后,需要在浏览器以附件的形式下载,所以可以用二进制的形式进行读取
excel = open(dest_filename,"rb")
# FileResponse 该类可以将文件下载到浏览器
response = FileResponse(excel)
response['Content-Type'] = 'application/octet-stream'
response['Content-Disposition'] = 'attachment;filename="{0}"'.format(file_name)
return response
注:因为列表的第五列time从数据库读出来是datatime类型,但是写入到excel表格变成了浮点数,所有上面先定义写入excel的时间格式,在写入time列的时候用自定义的时间格式写入.
如果写入excel表格的时间格式是对的,ws.write(row_num, col_num, row[col_num]) 可以用这个直接写入就行了
扩展:
文件下载的三种方式
方法一
def file_download(request, file_path):
with open(file_path, 'rb') as f:
try:
response = HttpResponse(f)
response['content_type'] = "application/octet-stream"
response['Content-Disposition'] = 'attachment; filename=' + os.path.basename(file_path)
return response
如果文件是个二进制文件,HttpResponse输出的将会是乱码。对于一些二进制文件(图片,pdf),我们更希望其直接作为附件下载。当文件下载到本机后,用户就可以根据自己喜欢的程序打开阅读文件了。这时我们可以对上述方法做出如下改进, 给response设置content_type和Content_Disposition。
HttpResponse有个很大的弊端,其工作原理是先读取文件,载入内存,然后再输出。如果下载文件很大,该方法会占用很多内存。对于下载大文件,Django更推荐StreamingHttpResponse和FileResponse方法,这两个方法将下载文件分批(Chunks)写入用户本地磁盘,先不将它们载入服务器内存。
方法二: 使用SteamingHttpResonse
def stream_http_download(request, file_path):
try:
response = StreamingHttpResponse(open(file_path, 'rb'))
response['content_type'] = "application/octet-stream"
response['Content-Disposition'] = 'attachment; filename=' + os.path.basename(file_path)
return response
方法三: 使用FileResonse
import os
from django.http import HttpResponse, Http404, FileResponse
def file_response_download1(request, file_path):
try:
response = FileResponse(open(file_path, 'rb'))
response['content_type'] = "application/octet-stream"
response['Content-Disposition'] = 'attachment; filename=' + os.path.basename(file_path)
return response
except Exception:
raise Http404
推荐使用第三种