python前端ajax后端django 文件下载功能,怎么提高下载速度

前端ajax 方法一(逻辑较简单):

<input id="downLoad" class="initDataAll" type="button" value="下载test"/>
<script type="text/javascript">
<!--下载-->
const DownloadCsv = (function() {
  const a = document.createElement("a");
  document.body.appendChild(a);
  a.style = "display: none";
  return function(data, fileName) {
    const blob = new Blob([data], {type: "octet/stream"}),
      url = window.URL.createObjectURL(blob);
    a.href = url;
    a.download = fileName;
    a.click();
    window.URL.revokeObjectURL(url);
  };
}());

$("#downLoad").click(function () {
    //发送ajax请求
    $.ajax({
        url: "/user/export_excel?tableName=branch",  //请求的url
        method: "post", //默认get
        xhrFields: {
                responseType: "arraybuffer",
           },
        success: function (response,status,request) { 
            DownloadCsv(response, 'branch.csv')
        }
    })
});
</script>

  

前端ajax方法二(代码较难点)

<input id="downLoad" class="initDataAll" type="button" value="下载test"/>
<script type="text/javascript">
<!--下载-->
$("#downLoad").click(function () {
    //发送ajax请求
    $.ajax({
        url: "/user/export_excel?tableName=branch",  //请求的url
        method: "post", //默认get
        xhrFields: {
                responseType: "arraybuffer",
           },
        success: function (response,status,request) {  //data接收响应体,必须要有
            let [, fileName] = request
            .getResponseHeader("Content-Disposition")
            .match(/filename=(.*)$/);
            let blob = new Blob([response], {
            type: "application/octet-stream",
            });
            let link = document.createElement("a");
            link.href = window.URL.createObjectURL(blob);
            <!--link.download = fileName;-->
            link.download = "branch.csv";
            link.click();
            window.URL.revokeObjectURL(link.href);
        }
    })
});
</script>

后端django 方法一(文件需要临时保存本地):
def export_excel(request):
    print('export_excel')
    try:
        tableName = request.GET.get('tableName')
        print('url参数:',[tableName])
        ret = [['我方的', 'tom', 'ssdf'], ['逆风', 'jerry', 'dsdfsd']]*1000
        df = pd.DataFrame(ret, columns=['id', 'name', 'age'])
        t1=time.time()
        file_path = "data/files/download/tem_download.csv"
        df.to_csv(file_path,index=False)
        f = open(file_path, 'rb')
        response = FileResponse(f,as_attachment=True)
        response['Content-Type'] = 'application/octet-stream'
        response['Content-Disposition'] = 'attachment;filename="{}.csv"'.format(tableName)
        t2 = time.time()
        print('时间 :',t2-t1)
        return response
    except Exception as e:
        print([e])
        return e

  代码说明:数据量超过10万以上时候

这里面占用时间最多的地方是:df.to_csv(file_path,index=False),一开始我保存的是xlsx格式,花费时间巨长,

后来保存为csv,40万条数据秒级完成。

---------------------------------------------------------------------------------------------------------------------------------------------------------------------

后端django 方法二:
def export_excel(request):
    print('export_excel')
    try:
        tableName = request.GET.get('tableName')
        print('url参数:',[tableName])
        ret = [['我方的', 'tom', 'ssdf'], ['逆风', 'jerry', 'dsdfsd']]*1000
        df = pd.DataFrame(ret, columns=['id', 'name', 'age'])
        # sent file bytes to front
        response = HttpResponse()
        response['Content-Type'] = 'application/vnd.ms-excel'
        # todo fileName
        response['Content-Disposition'] = 'attachment;filename="{}.csv"'.format(tableName)
        response['Accept-Encoding'] = 'gzip, deflate, br'
        out = _convert_df_to_bytes(df)
        if not out:
            raise RuntimeError("xxx")
        response.write(out.getvalue())
       
        return response
    except Exception as e:
        print([e])
        return e
#把文件转为二进制存在内存中
def _convert_df_to_bytes(df):
    output = io.BytesIO()  # todo 50M nginx
    df.to_csv(output, index=False)
    output.seek(0)
    return output

  说明:文件直接保存到内存中,不再保存到本地然后读取

 
posted @ 2022-05-03 22:08  简单音乐  阅读(581)  评论(2)    收藏  举报