owsata
owsata

Reputation: 1225

Save base64 string as PDF at client side with JavaScript

So here my problem: I have a pdf file as a base64 String that i am getting from the server. I would like to use this string to either display the PDF directly to the browser or give it a option of "Save as..." when clicking on a link. Here the code i am using:

<!doctype>
<html>
<head>
   <title>jsPDF</title>
   <script type="text/javascript" src="../libs/base64.js"></script>
   <script type="text/javascript" src="../libs/sprintf.js"></script>
   <script type="text/javascript" src="../jspdf.js"></script>

       <script type="text/javascript">

        function demo1() {
            jsPDF.init();
            jsPDF.addPage();
            jsPDF.text(20, 20, 'Hello world!');
            jsPDF.text(20, 30, 'This is client-side Javascript, pumping out a PDF.');

            // Making Data URI
            var out = jsPDF.output();
            var url = 'data:application/pdf;base64,' + Base64.encode(out);

            document.location.href = url;
         }
    </script>
</head>
<body>

<a href="javascript:demo1()">Run Code</a>

</body>
</html>

Its working fine with Chrome and Safari. Firefox does recognize the pdf but does not display it as FF requires extensions to be present but the data-URI has none in this case. The reason I'm insisting here, if chrome and safari get it to work, then there has to be a solution for FF and IE

I know there are a few relevant questions to this but not really the exact one and now also a bit old ones. I know a workaround would be to have the pdf generated at server side but I would like to generate it at client side.

So please intelligent folks, is it possible through some hacks or additional JS download plugins?

Upvotes: 87

Views: 262458

Answers (8)

Denys Sokolov
Denys Sokolov

Reputation: 83

You have two ways to embed PDF on the HTML page:

#1. Iframe

<iframe id="pdf_container" src="data:application/pdf;base64,JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwv..."></iframe>

#2. Embed

<embed id="pdf_container" src="data:application/pdf;base64,JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwv..."></embed>

Geted from embed PDF to HTML

I suggest using one place for "data:application/pdf;base64..." to save the page size and get data to download if needed from this place.

And JS to download content:

function download()
{
   var container = document.getElementById("pdf_container");

   var download_anchor = document.createElement("a")
   download_anchor.href = container.src; 
   download_anchor.download = "file.pdf"
   download_anchor.click();
}

Upvotes: 0

rob9099
rob9099

Reputation: 69

This worked for me:

const downloadLink = document.createElement("a")
downloadLink.href = 'data:application/octet-stream;base64,' + yourBase64Data
downloadLink.download = "convertedPDFFile.pdf"
downloadLink.click()

Upvotes: 0

Gabriel Cerutti
Gabriel Cerutti

Reputation: 1487

You can create an anchor like the one showed below to download the base64 pdf:

<a download="PDF Title" href="pdfData">Download PDF document</a>

where pdfData is your base64 encoded pdf like:

data:application/pdf;base64,JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0ZpbHRlci9GbGF0ZURlY29kZT4+CnN0cmVhbQp4nO1cyY4ktxG911fUWUC3kjsTaBTQ1Ytg32QN4IPgk23JMDQ2LB/0+2YsZAQzmZk1PSPIEB...

Upvotes: 57

Manas Sahu
Manas Sahu

Reputation: 907

function dataURItoBlob(dataURI) {
      const byteString = window.atob(dataURI);
      const arrayBuffer = new ArrayBuffer(byteString.length);
      const int8Array = new Uint8Array(arrayBuffer);
      for (let i = 0; i < byteString.length; i++) {
        int8Array[i] = byteString.charCodeAt(i);
      }
      const blob = new Blob([int8Array], { type: 'application/pdf'});
      return blob;
    }

// data should be your response data in base64 format

const blob = this.dataURItoBlob(data);
const url = URL.createObjectURL(blob);

// to open the PDF in a new window
window.open(url, '_blank');

Upvotes: 21

adnan javed
adnan javed

Reputation: 1518

you can use this function to download file from base64.

function downloadPDF(pdf) {
const linkSource = `data:application/pdf;base64,${pdf}`;
const downloadLink = document.createElement("a");
const fileName = "abc.pdf";
downloadLink.href = linkSource;
downloadLink.download = fileName;
downloadLink.click();}

This code will made an anchor tag with href and download file. if you want to use button then you can call click method on your button click.

i hope this will help of you thanks

Upvotes: 83

Hoang Subin
Hoang Subin

Reputation: 7400

You will do not need any library for this. JavaScript support this already. Here is my end-to-end solution.

const xhr = new XMLHttpRequest();
xhr.open('GET', 'your-end-point', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
xhr.responseType = 'blob';
xhr.onreadystatechange = function () {
    if (this.readyState == 4 && this.status == 200) {
       if (window.navigator.msSaveOrOpenBlob) {
           window.navigator.msSaveBlob(this.response, "fileName.pdf");
        } else {
           const downloadLink = window.document.createElement('a');
           const contentTypeHeader = xhr.getResponseHeader("Content-Type");
           downloadLink.href = window.URL.createObjectURL(new Blob([this.response], { type: contentTypeHeader }));
           downloadLink.download = "fileName.pdf";
           document.body.appendChild(downloadLink);
           downloadLink.click();
           document.body.removeChild(downloadLink);
        }
    }
};
xhr.send(null);

This also work for .xls or .zip file. You just need to change file name to fileName.xls or fileName.zip. This depends on your case.

Upvotes: 2

Ka0s
Ka0s

Reputation: 398

I know this question is old, but also wanted to accomplish this and came across it while looking. For internet explorer I used code from here to save a Blob. To create a blob from the base64 string there were many results on this site, so its not my code I just can't remember the specific source:

function b64toBlob(b64Data, contentType) {
    contentType = contentType || '';
    var sliceSize = 512;
    b64Data = b64Data.replace(/^[^,]+,/, '');
    b64Data = b64Data.replace(/\s/g, '');
    var byteCharacters = window.atob(b64Data);
    var byteArrays = [];

    for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
        var slice = byteCharacters.slice(offset, offset + sliceSize);

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

        var byteArray = new Uint8Array(byteNumbers);

        byteArrays.push(byteArray);
    }

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

Using the linked filesaver:

if (window.saveAs) { window.saveAs(blob, name); }
    else { navigator.saveBlob(blob, name); }

Upvotes: 18

Denys S&#233;guret
Denys S&#233;guret

Reputation: 382092

You should be able to download the file using

window.open("data:application/pdf;base64," + Base64.encode(out));

Upvotes: 27

Related Questions