使用django时下载xlsx的方法,同样适用于其他类型的文件。
使用openpyxl库生成xlsx文件,使用save_virtual_workbook方法将文件保存到内存中,然后发送给客户端。
重要的是要设置response的content_type,根据不同的文件类型进行设置,xlsx的是'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',还要设置Content-Disposition为'attachment; filename=test.xlsx'。
服务端示例如下:
from openpyxl import Workbook
from django.http import HttpResponse
from openpyxl.writer.excel import save_virtual_workbook
from openpyxl.styles import Border, Font, Side, Alignment
def get_xlsx(request):
sheel_name = 'test'
datas = []
workbook = Workbook()
sheet = workbook.active
sheet.title = sheel_name
border = Border(*([Side(style='thin', color='000000')] * 4))
rows, columns = len(datas), len(datas[0])
max_width = 0
for row in range(rows):
sheet.row_dimensions[row + 1].height = 18
for column in range(columns):
the_cell = sheet['%s%s' % (chr(column + 65), row + 1)]
the_cell.value, the_cell.border = datas[row][column], border
if row > 0:
if column == 3:
if '\n' in the_cell.value:
the_cell.alignment = Alignment(horizontal='left', vertical='top')
else:
the_cell.alignment = Alignment(horizontal='left', vertical='center')
if len(the_cell.value) > max_width:
max_width = len(the_cell.value)
elif column == columns - 1:
the_cell.alignment = Alignment(horizontal='right', vertical='center')
the_cell.number_format = '0.00 '
else:
the_cell.alignment = Alignment(horizontal='center', vertical='center')
else:
the_cell.alignment = Alignment(horizontal='center', vertical='center')
for column in range(columns):
sheet['%s1' % chr(column + 65)].font = Font(bold=True)
column_width = 20 if column < 3 else (12 if column > 3 else (int(max_width * 1.58) or 30))
sheet.column_dimensions[chr(column + 65)].width = column_width
workbook.close()
response = HttpResponse(save_virtual_workbook(workbook), content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = 'attachment; filename=%s.xlsx' % sheel_name
return response
客户端使用ajax请求获取表格文件数据,然后创建一个包含数据的虚拟链接作为a标签的链接,触发a标签后删除a标签。重要的是ajax请求中要设置参数xhrFields: {responseType: 'blob'},这样才能正常识别文件。
JS兼容性示例如下:
$(".download")[0].onclick = function () {
$.ajax({
method:'POST',
url:'...',
data: {...},
xhrFields: {responseType: 'blob'},
success:function (blob) {
var filename = 'test.xlsx',
URL = window.URL || window.webkitURL,
bloburl = URL.createObjectURL(blob),
anchor = document.createElement("a");
if ('download' in anchor) {
anchor.style.visibility = "hidden";
anchor.href = bloburl;
anchor.download = filename;
document.body.appendChild(anchor);
var evt = document.createEvent("MouseEvents");
evt.initEvent("click", true, true);
anchor.dispatchEvent(evt);
document.body.removeChild(anchor);
} else if (navigator.msSaveBlob) {
navigator.msSaveBlob(blob, filename);
} else {
location.href = bloburl;
}
},
fail:function () {}
})
};