Getting corrupted file while exporting .xls file u

2019-08-03 20:30发布

问题:

I am trying to downlaod a .xls file in browser from a web application. Below is the code for the same.

try(FileInputStream inputStream = new FileInputStream("C:\\Users\\Desktop\\Book1.xls")){
            response.setContentType("application/vnd.ms-excel");
            //response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("Content-Disposition", "attachment; filename=Book1.xls");
            outputStream = response.getOutputStream();
            byte[] buffer = new byte[BUFFERSIZE];
            int bytesRead = -1;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
        }

Below is the javascript code used to download the file content.

success: function(response, status, xhr) {

                let type = xhr.getResponseHeader('Content-Type');
                let blob = new Blob([response], { type: type });

                if (typeof window.navigator.msSaveBlob !== 'undefined') {
                    // IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created.
                    //These URLs will no longer resolve as the data backing the URL has been freed."
                    window.navigator.msSaveBlob(blob, filename);
                } else {
                    let URL = window.URL || window.webkitURL;
                    let downloadUrl = URL.createObjectURL(blob);
                    if (filename) {
                        // use HTML5 a[download] attribute to specify filename
                        let a = document.createElement("a");
                        // safari doesn't support this yet
                        if (typeof a.download === 'undefined') {
                            window.location = downloadUrl;
                        } else {
                            a.href = downloadUrl;
                            a.download = filename;
                            document.body.appendChild(a);
                            a.click();
                        }
                    } else {
                        window.location = downloadUrl;
                    }
                    setTimeout(function () {
                        URL.revokeObjectURL(downloadUrl);
                    }, 100); // cleanup
                }
            }

I am able to download the file, but downloaded file content is not in readble format. If it is csv file I am able to see content in my javascript response object where as for .xls file javascript response object contains unreadable formatted data.

Can somebody help me here?

回答1:

Posting this solution if anyone else faces the same issue, I resolved this issue via base64 encoding the byte array to a string as below.

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
 workbook.write(outputStream);
 String res = Base64.getEncoder().encodeToString(outputStream.toByteArray());

In javascript I decoded that string using base64ToBlob method from below link

https://stackoverflow.com/a/20151856/2011294

function base64toBlob(base64Data, contentType) {
    contentType = contentType || '';
    var sliceSize = 1024;
    var byteCharacters = atob(base64Data);
    var bytesLength = byteCharacters.length;
    var slicesCount = Math.ceil(bytesLength / sliceSize);
    var byteArrays = new Array(slicesCount);

    for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
        var begin = sliceIndex * sliceSize;
        var end = Math.min(begin + sliceSize, bytesLength);

        var bytes = new Array(end - begin);
        for (var offset = begin, i = 0; offset < end; ++i, ++offset) {
            bytes[i] = byteCharacters[offset].charCodeAt(0);
        }
        byteArrays[sliceIndex] = new Uint8Array(bytes);
    }
    return new Blob(byteArrays, { type: contentType });
}