XLSX客户端从后端api响应保存:二进制字符串,应用程序/八位字节流

时间:2018-12-19 21:00:44

标签: javascript file save blob xlsx

我需要将XLSX文件保存在从XHR到api的前端。

在api响应中,我得到了以下标头:

    Content-Type: application/octet-stream
    content-disposition: attachment; filename = OrdersList-253CREATED0.xlsx

以及响应主体的一部分:

PKõzMdocProps/core.xml­MKÄ0ïý!÷vVd-mQÅ++ÞB:¶Åæ$Úõßí®Å£ÇÉû¼Ã¤\ïåHÞѺA«²$¥Ðí º>6xE×uB[ÜZmÐú -å*Ú{o 'zÜ%!V!yÑVrFÛáâwYDÏ[î9l±Ytôè+ùwe+¥y³ã,hàwÀ߬G+Ý9YȽj¦dÊg.lÄàéîöa^>ó\ ¤uDHy²Â"÷Øà(üÁ~%»üêºÙÐ:KÙ*fYÌ.,-²¼8ËKøÕ?9£¶õe8Kd{ ...

在我的代码中,我尝试了很多选择:

1)将类型:“ application / octet-stream”替换为application / vnd.openxmlformats-officedocument.spreadsheetml.sheet

2)创建不带s2ab函数的blob /文件,例如Blob([binary_string],...)

let binary_string = response;

// Download using blob:
let ab = s2ab(binary_string),
    blob = new Blob(
                [ab],
                {type: "application/octet-stream"}
            );

let downloadLink = document.createElement('a');
downloadLink.href = URL.createObjectURL(blob);
downloadLink.download = 'test-blob.xlsx';
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);

// Download using file
let FileSaver = require('file-saver'),
            ab = s2ab(binary_string),
            file = new File(
                [ab], 
                "test-file.xlsx", 
                {type: "application/octet-stream"});

FileSaver.saveAs(file);

// s2ab function
function s2ab(s) {
    var buf = new ArrayBuffer(s.length);
    var view = new Uint8Array(buf);
    for (var i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
    return buf;
}

为什么我不能只使用iframe或[下载]?因为需要授权标头。

响应文件是正确的,通过邮递员加载时会打开,但是当我试图通过XHR响应中的js保存文件时,它总是损坏。

我将非常感谢您的帮助:)

1 个答案:

答案 0 :(得分:0)

我解决了这个问题。 在这个项目中,我使用react,因此,我将axios用于ajax请求。

我认为某些axios设置或axios本身存在问题;

香草js上的工作代码示例:

var request = new XMLHttpRequest();
    request.open('GET', `http://localhost/api/get_xlsx`, true);
    request.setRequestHeader('Token', 'user_auth_token_needed_in_my_app');
    request.responseType = 'blob';

    request.onload = function(e) {
        if (this.status === 200) {
            var blob = this.response;
            if(window.navigator.msSaveOrOpenBlob) {
                window.navigator.msSaveBlob(blob, 'test.xlsx');
            }
            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 = 'test.xlsx';
                document.body.appendChild(downloadLink);
                downloadLink.click();
                document.body.removeChild(downloadLink);
            }
        }
    };
    request.send();