我们知道ajax 能发送POST 请求,完成页面内容的刷新, 一般返回数据是json。 而常用的download的操作,都是GET请求。当我们需要根据前端的查询条件,如何在页面不刷新的条件下完成相应数据的下载呢?
1. 最终成果
2. 代码思路
前端思路:
前端利用ajax 将查询条件POST 到后端,然后根据后端返回的值,JS open(GET方式)相应的URL, 实现下载。
后端思路:
根据前段POST 的参数,进行数据库的查询,并导出Excel 到服务器指定文件夹,完成后返回文件名到前端。前端根据post的返回值,发起GET请求,并将文件名作为参数提交到后端, 最终实现下载。
3. 代码实现
3.1 前端代码
界面UI
<div class="col-md-3"></div>
<div class="col-md-6" style="padding-left:7%">
<label for="ftp_time" >ETD:</label>
<label>
<input type="text" id = "etd_time_start" class="form-control form_datetime" style="width: 120px">
</label>
---
<label>
<input type="text" id = "etd_time_end" class="form-control form_datetime" style="width: 120px">
</label>
<label>
<input class="btn btn-success" type="submit" onclick ="qureyBooking()" value="Filter" >
<input class="btn btn-info" type="submit" onclick ="clearBtn()" value="Cancel" >
</label>
</div>
<div class="col-md-3">
<input class="btn btn-info" type="submit" onclick ="DownloadBtn()" value="Download" >
</div>
JS 部分:
function DownloadBtn(){
var form_data = new FormData();
form_data.append('start_time', $('#etd_time_start').val());
form_data.append('end_time',$('#etd_time_end').val());
$.ajax({
url:'/api/ajax_download/',
type:'POST',
data: form_data,
processData: false, // tell jquery not to process the data
contentType: false, // tell jquery not to set contentType
success: function(data) {
console.log('OK')
open("/api/ajax_download?file_name="+ data)
},
error: function(data) {alert("error")}
});
}
3.2 后台代码
urls.py 部分代码
url(r'^api/ajax_download/$', views.download_booking_API),
views.py :
from django.http import StreamingHttpResponse
import time
# 当前文件目录
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
def file_iterator(file_name, chunk_size=512):#用于形成二进制数据
with open(file_name,'rb') as f:
while True:
c = f.read(chunk_size)
if c:
yield c
else:
break
def download_booking_API(request):
time_stamp= time.strftime("%Y-%m-%d_%H%M%S", time.localtime())
response = ""
if request.method == "POST":
print("download_booking_API")
start_time = '2020-01-01'
end_time = '2030-01-01'
if request.POST.get("start_time"):
start_time = request.POST.get("start_time")
if request.POST.get("end_time"):
end_time = request.POST.get("end_time")
all_report = Name.objects.filter(ETD__range = [start_time,end_time])
report_list = list()
if len(all_report)>0:
for obj in all_report:
dic_data = {
"id": obj.id,
"name": obj.name,
"Weight": obj.Weight,
'upload_time': obj.log_time.strftime("%Y-%m-%d %H:%M:%S"),
}
report_list.append(dic_data)
# save data by excel file
DF = pd.DataFrame(report_list)
file_path = os.path.join(BASE_DIR, 'workload','download',time_stamp +".xlsx" )
DF.to_excel(file_path,index = False)
# 返回时间戳(文件名)
return HttpResponse(time_stamp)
else:
file_name = request.GET.get('file_name')
print('file_name')
print(file_name)
file_path = os.path.join(BASE_DIR, 'workload','download',file_name+".xlsx" )
response =StreamingHttpResponse(file_iterator(file_path)) #这里创建返回
response['Content-Type'] = 'application/vnd.ms-excel' #注意格式
response['Content-Disposition'] = 'attachment;filename="booking_%s.xlsx"'% file_name
#注意filename 这个是下载后的名字
return response
结束
参考:
link https://blog.csdn.net/u014686399/article/details/78198306