Home > Enterprise >  Javascript download BLOB as PDF
Javascript download BLOB as PDF

Time:12-22

I am trying to convert a blob object to a pdf and download it.

So far I've tried the following:

var downloadLink = document.createElement('a');
            downloadLink.target = '_blank';
            downloadLink.download = 'name_to_give_saved_file.pdf';

            // convert downloaded data to a Blob
            var blob = new Blob([file.$binary], { type: 'application/pdf' });

            // create an object URL from the Blob
            var URL = window.URL || window.webkitURL;
            var downloadUrl = URL.createObjectURL(blob);

            // set object URL as the anchor's href
            downloadLink.href = downloadUrl;

            // append the anchor to document body
            document.body.append(downloadLink);

            // fire a click event on the anchor
            downloadLink.click();

The file size seems to be correct, but I cant view it since it seems to be damaged.

Viewing the PDF inside of my html file works like this:

 $('#test').html('<embed width=100% height=100%'
              ' type="application/pdf"'
              ' src="data:application/pdf;base64,'
              escape(file.$binary)
              '"></embed>')

This works without any problems!

Now to my question... why is one working and the other one isn't?

Thanks for your help...

CodePudding user response:

Your file.$binary is not binary data (even though the object name is `$binary). It's actually a string containing the base64 representation of binary data.

So, before making a Blob, you need to convert the string to the binary data.

You can do so using the following (from https://stackoverflow.com/a/16245768):

const b64toBlob = (b64Data, contentType='', sliceSize=512) => {
  const byteCharacters = atob(b64Data);
  const byteArrays = [];

  for (let offset = 0; offset < byteCharacters.length; offset  = sliceSize) {
    const slice = byteCharacters.slice(offset, offset   sliceSize);

    const byteNumbers = new Array(slice.length);
    for (let i = 0; i < slice.length; i  ) {
      byteNumbers[i] = slice.charCodeAt(i);
    }

    const byteArray = new Uint8Array(byteNumbers);
    byteArrays.push(byteArray);
  }

  const blob = new Blob(byteArrays, {type: contentType});
  return blob;
}

Then you can do

var blob = b64toBlob(file.$binary, 'application/pdf');

Looking at other answers on the same question (https://stackoverflow.com/a/36183085), there is a smaller way to do this:

const b64toBlob = (base64, type = 'application/octet-stream') => 
    fetch(`data:${type};base64,${base64}`).then(res => res.blob())

Then you can still do

var blob = b64toBlob(file.$binary, 'application/pdf');
  • Related