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?
解决方案
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
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 });
}