javascriptfileblobxlsx

Javascript - Download xls file served from backend in blob format


I have a backend service writted in Java that will power the vue frontend app. I need to start the download of a file when it will be provided from the backend. At the moment I've noticed that the response fro the backend that will provide the file is an object. The object have this structure:

{
 data: "..." //This is supposed to be a blob
}

How I can convert the response to an xls file correctly? I've tried to pass it to the File consctructor but the resulting file seems corrupted.

getXlsFile(data)
 .then( (res) => {
   let file = new File([res?.data], 'report.xls');
   ...
  })

Not sure if I need to convert the response in a blob again?

UPDATE

I saw from the dev console in the network tab that the response is in base64 format, but what I see if i do a console log of the response are a strange set of chars. I've tried to convert the rsponse from the network tab using an online tool and seems correct the resulting file.

How I can check if the response is in base64 and eventually create a blob from it for the download?


Solution

  • You can try to use the javascript Blob to convert and then force the file dowload

    This is a working function in my utils.js (this downloads a txt file from a textarea element)

    function generateTextFile(textareaElement, filenameWithoutExtension) {
        var textToWrite = textareaElement.val();
        var textFileAsBlob = new Blob([textToWrite], { type: 'text/plain' });
        var fileNameToSaveAs = filenameWithoutExtension + ".txt" //Your filename;
    
        var downloadLink = document.createElement("a");
        downloadLink.download = fileNameToSaveAs;
        downloadLink.innerHTML = "Download File";
        if (window.webkitURL != null) {
            // Chrome allows the link to be clicked
            // without actually adding it to the DOM.
            downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
        }
        else {
            // Firefox requires the link to be added to the DOM
            // before it can be clicked.
            downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
            downloadLink.onclick = destroyClickedElement;
            downloadLink.style.display = "none";
            document.body.appendChild(downloadLink);
        }
    
        downloadLink.click();
    }
    

    You should try something like this: (not tested)

        var textFileAsBlob = new Blob([blobFromYourBackend], { type: 'application/vnd.ms-excel' });
        var fileNameToSaveAs = "myexcel.xls" //Your filename;
    
        var downloadLink = document.createElement("a");
        downloadLink.download = fileNameToSaveAs;
        downloadLink.innerHTML = "Download File";
        if (window.webkitURL != null) {
            // Chrome allows the link to be clicked
            // without actually adding it to the DOM.
            downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
        }
        else {
            // Firefox requires the link to be added to the DOM
            // before it can be clicked.
            downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
            downloadLink.onclick = destroyClickedElement;
            downloadLink.style.display = "none";
            document.body.appendChild(downloadLink);
        }
    
        downloadLink.click();
    

    Other option to try:

    var textToWrite = [blobFromYourBackend];
    var l = document.createElement("a");
    l.href = "data:application/vnd.ms-excel;charset=UTF-8," + textToWrite;
    l.setAttribute("download", "myexcel.xls");
    l.click();