2

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?

3
  • 1
    Check this out stackoverflow.com/questions/11226603/… Hope it helps, thanks. Commented Jul 23, 2018 at 6:36
  • Tried the above link as well, still getting same error. It seems there is some issue in java code. Either it is MIME type resolution or character encoding issue. Commented Jul 23, 2018 at 11:20
  • Found one more link with same issue.. stackoverflow.com/questions/17421422/… Can someone help me out here to find the issue? I have tried sending the workbook data as file and byte stream as well, but in both scenarios I can see some special characters ��ࡱ�;������������ï¿. seems like unicode characters. Commented Jul 24, 2018 at 2:56

1 Answer 1

3

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 });
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.