从Ajax中的服务器响应获取Excel文件(.xlsx) [英] Get excel file (.xlsx) from server response in ajax

查看:1199
本文介绍了从Ajax中的服务器响应获取Excel文件(.xlsx)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在获得对该文件的响应(成功的ajax方法)后,获取Excel文件并在浏览器中打开下载窗口时出现问题。我有合适的 Content-Type和Content-Disposition标头,我尝试在JS中使用 Blob ,但我无法实现我想要的目标-简单文件下载。

我完成了几个版本的ajax,下面是其中的一个。我开发了ajax,它返回的excel文件由于损坏而无法正确打开(尽管扩展名为.xlsx)。

I have got a problem with getting excel file and opening download window in the browser after getting a response (in success ajax method) with that file. I have got appropriate Content-Type and Content-Disposition headers, I tried using Blob in js and I couldn't achieve what I want - simple file downloading.
I accomplished few versions of my ajax, one of them is below. I developed ajax which returns excel file which I couldn't open properly because it's corrupted (despite .xlsx extension).

也许问题出在Blob构造函数中使用的数据类型不合适?

Maybe the problem is with inappropriate data type used in Blob constructor?

我尝试使用 xhr.response代替成功方法参数中的 data,但是它也无法正常工作。我检查了Chrome开发人员工具中的响应标题,并且它们的设置正确。

重要的是-在服务器端创建的所有excel工作簿都是正确的,因为当在URL中发送数据时,该工作簿在以前的版本中有效

I tried using "xhr.response" instead of "data" from success method arguments but it doesn't work too. I checked Response Headers in Developer Tools in Chrome and they are set properly.
The important thing - all the excel workbooks created on the server side is correct because it worked in the previous version when data was sent in URL, not in ajax post.

下面的Java / Spring服务器端的控制器方法:

Controller method in Java/Spring server side below:

response.reset();
response.setContentType("application/vnd.ms-excel");
response.addHeader("Content-Disposition","attachment;filename=\"" + className + " " +  title + ".xlsx\"");
    try (ServletOutputStream output = response.getOutputStream()){
        workbook.write(output);
        output.flush();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }

我的Ajax下载文件并打开下载窗口:

My Ajax to download file and open download window:

$.ajax({
    url: myUrl,
    type: 'POST',
    data: myData,
    success: function(data, status, xhr) {
        var contentType = 'application/vnd.ms-excel';

        var filename = "";
        var disposition = xhr.getResponseHeader('Content-Disposition');
        if (disposition && disposition.indexOf('attachment') !== -1) {
            var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
            var matches = filenameRegex.exec(disposition);
            if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
        }
        console.log("FILENAME: " + filename);

        try {
            var blob = new Blob([data], { type: contentType });

            var downloadUrl = URL.createObjectURL(blob);
            var a = document.createElement("a");
            a.href = downloadUrl;
            a.download = filename;
            document.body.appendChild(a);
            a.click();

        } catch (exc) {
            console.log("Save Blob method failed with the following exception.");
            console.log(exc);
        }


推荐答案

看起来JQuery有了处理响应中的二进制数据有些问题。我只是使用XMLHttpRequest并将所有数据添加到URL。

It looks like JQuery have got some problem with dealing with the binary data from the response. I used simply XMLHttpRequest and I add all data to the URL.

var request = new XMLHttpRequest();
request.open('POST', url, true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
request.responseType = 'blob';

request.onload = function(e) {
    if (this.status === 200) {
        var blob = this.response;
        if(window.navigator.msSaveOrOpenBlob) {
            window.navigator.msSaveBlob(blob, fileName);
        }
        else{
            var downloadLink = window.document.createElement('a');
            var contentTypeHeader = request.getResponseHeader("Content-Type");
            downloadLink.href = window.URL.createObjectURL(new Blob([blob], { type: contentTypeHeader }));
            downloadLink.download = fileName;
            document.body.appendChild(downloadLink);
            downloadLink.click();
            document.body.removeChild(downloadLink);
           }
       }
   };
   request.send();

这篇关于从Ajax中的服务器响应获取Excel文件(.xlsx)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆