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();
            }
        }
    })
});

這樣就可以下載文件了,後臺根據前端值不同選擇不同的文件發送。

下載效果如下:

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