Download File from Bytes in JavaScript

137,698

Solution 1

I asked the question long time ago, so I might be wrong in some details.

It turns out that Blob needs array buffers. That's why base64 bytes need to be converted to array buffers first.

Here is the function to do that:

function base64ToArrayBuffer(base64) {
    var binaryString = window.atob(base64);
    var binaryLen = binaryString.length;
    var bytes = new Uint8Array(binaryLen);
    for (var i = 0; i < binaryLen; i++) {
       var ascii = binaryString.charCodeAt(i);
       bytes[i] = ascii;
    }
    return bytes;
 }

Here is my function to save a pdf file:

function saveByteArray(reportName, byte) {
    var blob = new Blob([byte], {type: "application/pdf"});
    var link = document.createElement('a');
    link.href = window.URL.createObjectURL(blob);
    var fileName = reportName;
    link.download = fileName;
    link.click();
};

Here is how to use these two functions together:

var sampleArr = base64ToArrayBuffer(data);
saveByteArray("Sample Report", sampleArr);

Solution 2

You just need to add one extra line and it should work. Your response is byte array from your server application

var bytes = new Uint8Array(resultByte); // pass your byte response to this constructor

var blob=new Blob([bytes], {type: "application/pdf"});// change resultByte to bytes

var link=document.createElement('a');
link.href=window.URL.createObjectURL(blob);
link.download="myFileName.pdf";
link.click();

Solution 3

Set Blob type at Blob constructor instead of at createObjectURL

var blob = new Blob([resultByte], {type: "application/pdf"});
var link = document.createElement("a");
link.href = window.URL.createObjectURL(blob);
link.download = "myFileName.pdf";
link.click();
Share:
137,698

Related videos on Youtube

Jahongir Rahmonov
Author by

Jahongir Rahmonov

Software Engineer at Delivery Hero rahmonov.me

Updated on July 05, 2022

Comments

  • Jahongir Rahmonov
    Jahongir Rahmonov almost 2 years

    I want to download the file which is coming in the form of bytes from the AJAX response.

    I tried to do it this way with the help of Blob:

    var blob=new Blob([resultByte], {type: "application/pdf"});
    var link=document.createElement('a');
    link.href=window.URL.createObjectURL(blob);
    link.download="myFileName.pdf";
    link.click();
    

    It is in fact downloading the pdf file but the file itself is corrupted.

    How can I accomplish this?

    • runlevelsix
      runlevelsix almost 8 years
      This is a bit of a +1 comment. I'm trying to do the same thing, and with the same results - a corrupted PDF. The PDF will open, has the same number of pages I expect, but there is no text. I suspect the issue lies in either the encoding of the PDF, or the conversion of it from [resultByes] to a blob... I would like to hear if you came up with a solution.
    • Jahongir Rahmonov
      Jahongir Rahmonov almost 8 years
      @runlevelsix, yes I figured that out! Please see my answer below and see if it works for you too
  • mihkov
    mihkov about 6 years
    For me, the code is not working in Firefox 58.0.2, It executes with no errors, but the download dialog doesn't appear. I need to append the link to body and it works. bugzilla.mozilla.org/show_bug.cgi?id=1091035
  • Ankita
    Ankita almost 6 years
    I am returning base64 from server side and while use your method it gives me an error : Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.
  • combatc2
    combatc2 over 5 years
    To avoid the "failed to execute 'atob' on 'window'" error I had to return the data from my MVC action as JSON (as opposed to a FileResult / FileContentResult)
  • Mike
    Mike over 5 years
    I had the same issue and in my case the solution was to assure that I transfer data from the server side to client side in a proper Base64 format. Once I did it, your solution worked for me. Thanks a lot.
  • bender
    bender over 5 years
    For those with problems with downloads not working in Firefox or IE. Change: link.click() to link.dispatchEvent(new MouseEvent(click, {bubbles: true, cancelable: true, view: window}));
  • Roy Oliver
    Roy Oliver over 5 years
    @bender, you left the 'click' without quotes: link.dispatchEvent(new MouseEvent('click', {bubbles: true, cancelable: true, view: window}));
  • Dan Leksell
    Dan Leksell over 4 years
    I had to add this line document.body.appendChild(link); after link.href = window.URL.createObjectURL(blob);. Worked perfectly after that!
  • s.j
    s.j almost 3 years
    getting error of "TypeError: base64ToArrayBuffer is not a function" when i called this method to convert bytecode to buffer
  • Gutsygibbon
    Gutsygibbon almost 3 years
    excellent! I was stuck on converting the Binary String to Byte Array. Thanks for that function!