Django Ajax下载文件(动态文件下载实现)

前端埋一个隐藏的表单,用于传值:
<form id="hidden_form">
    {% csrf_token %}
    <input type="hidden" id="flag" name="flag">
    <input type="hidden" id="country" name="country">
    <input type="hidden" id="datatype" name="datatype">
</form>

python后端如下:(这段代码用于动态生成一个文件)

from django.views.decorators.csrf import csrf_exempt
# 需要提供一个参数type
# 下载功能

# 屏蔽掉csrf
@csrf_exempt
def download_file(request):
    import os

    from django.http import HttpResponse, FileResponse
    from django.shortcuts import render

    if request.method == "GET":
        return render(request, "COVID_19Analyse/filedown.html")

    # 获取操作类型
    try:
        type = request.POST.get("datatype")
    except Exception as e:
        return HttpResponse("你所访问的页面不存在", status=404)
    print(type)
    if type=="details":
        try:
            country = request.POST.get("country")
            print(country)
        except Exception as e:
            return HttpResponse("你所访问的页面不存在", status=404)
    else:
        country=""

    from ...tools.ExcelOpt import ExcelSpool
    excel = ExcelSpool()
    print(type)
    path = os.path.abspath(os.path.dirname(__file__))
    path = os.path.abspath(os.path.dirname(path) + os.path.sep + "..")


    the_file_name = getFileName(type,country)
    if the_file_name==False:
        print("111")
        return HttpResponse("你所访问的页面不存在", status=404)
    # 文件名 存储路径
    filename = path + '/static/COVID_19Analyse/Upload/' + the_file_name
    print(filename)

    if judge_exit(filename)==False:
        # 不存在该文件
        # 获取数据
        createFile(filename,type,country)
    # 发送文件
    file = open(filename, "rb")
    response = FileResponse(file)
    response['Content-Type'] = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    response['Content-Disposition'] = 'attachment; ' \
                                      'filename=' + the_file_name.encode('utf-8').decode('ISO-8859-1')

    return response


def judge_exit(file_path):
    import os
    if(os.path.exists(file_path)):
        return True
    return False

def getFileName(type,country=""):
    if type == "maincountry":
        the_file_name = "主要国家.xlsx"
    elif type == "plc":
        the_file_name = "人口大国.xlsx"
    elif type == "continent":
        the_file_name = "大洲情况.xlsx"
        pass
    elif type == "trend":
        the_file_name = "全球趋势.xlsx"
    elif type == "rank":
        the_file_name = "全球榜单.xlsx"
    elif type == "details":
        the_file_name = "country/"+country+".xlsx"
    else:
        return False
    return the_file_name

def createFile(filename,type,country=""):
    from ...tools.ExcelOpt import ExcelSpool
    from .data.ToExcelData import ToExcelData

    excel = ExcelSpool()

    if type == "maincountry":
        results = ToExcelData.getMainCountryDetails()
        excel.dictdictlist2excel(filename, results)
    elif type == "plc":
        results = ToExcelData.peopleLargeCountryConfirm()
        excel.dict_2DList2excel(filename, results)
    elif type == "continent":
        results = ToExcelData.continentConfirm()
        excel.dict_2DList2excel(filename, results)
        pass
    elif type == "trend":
        results = ToExcelData.getOverseaTrend()
        excel.dictlist2excel(filename, "海外疫情数据", results)
    elif type == "rank":
        results = ToExcelData.getRank()
        excel.dictdictlist2excel(filename, results)
    elif type == "details":
        from ...models import Country
        try:
            countryDataModels = (Country.objects.get(name=country).countrydata_set.all().order_by("-date"))
            excel.modellist2excel(filename, country, countryDataModels)
        except Exception as e:
            print(str(e))
            return False

因为用ajax实现的时候,其实是提交了两遍表单的,第二次的表单提交才是下载,我的错误就是第二次没有使用参数,因此后台识别不了,无法动态生成文件,控制台如下:

可以看见第一次表单是有值的,第二次没有,因此考虑第二次时,构造一个参数表单提交。JS代码如下:

$("a[name='rankdata']").bind("click", function () {
    $("#datatype").val("rank");
    var input1 = $('<input>');
    input1.attr('type', 'hidden');
    input1.attr('name', 'datatype');
    input1.attr('value', $("#datatype").val());
    var input2 = $('<input>');
    input2.attr('type', 'hidden');
    input2.attr('name', 'country');
    input2.attr('value', $("#country").val());
    $.ajax({
        url: "/data/download/",
        type: "POST",
        data: $("#hidden_form").serialize(),
        success: function (response, status, request) {
            var disp = request.getResponseHeader('Content-Disposition');
            if (disp && disp.search('attachment') != -1) { //判断是否为文件
                var form = $('<form action="/data/download/" method="post"></form>');
                $('body').append(form);
                form.append(input1);
                form.append(input2);
                form.submit();
            }
        }
    })
});

这样就可以下载文件了,后台根据前端值不同选择不同的文件发送。

下载效果如下:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章