Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pdf.js: rendering a pdf file using a base64 file source instead of url

I'm trying to render a page from a pdf with pdf.js

Normally, using a url, I can do this:

PDFJS.getDocument("http://www.server.com/file.pdf").then(function getPdfHelloWorld(pdf) {   //   // Fetch the first page   //   pdf.getPage(1).then(function getPageHelloWorld(page) {     var scale = 1.5;     var viewport = page.getViewport(scale);      //     // Prepare canvas using PDF page dimensions     //     var canvas = document.getElementById('the-canvas');     var context = canvas.getContext('2d');     canvas.height = viewport.height;     canvas.width = viewport.width;      //     // Render PDF page into canvas context     //     page.render({canvasContext: context, viewport: viewport});   }); }); 

But in this case, I have the file in base64 rather than an url:

data:application/pdf;base64,JVBERi0xLjUKJdDUxdgKNSAwIG9iaiA8PAovTGVuZ3RoIDE2NjUgICAgICAKL0ZpbHRlciAvRmxhdGVEZWNvZGUKPj4Kc3RyZWFtCnjarVhLc9s2... 

How this can be done?

like image 936
Alex Avatar asked Aug 23 '12 13:08

Alex


People also ask

Can you Base64 encode a PDF?

Base64 encoding is used to encode binary data, such as a PDF file, into an ASCII string format that is compatible with systems that can only handle text. For example, email attachments and binary uploads in HTML forms are converted and transmitted as Base64 encoded data.


2 Answers

from the sourcecode at http://mozilla.github.com/pdf.js/build/pdf.js

/**  * This is the main entry point for loading a PDF and interacting with it.  * NOTE: If a URL is used to fetch the PDF data a standard XMLHttpRequest(XHR)  * is used, which means it must follow the same origin rules that any XHR does  * e.g. No cross domain requests without CORS.  *  * @param {string|TypedAray|object} source Can be an url to where a PDF is  * located, a typed array (Uint8Array) already populated with data or  * and parameter object with the following possible fields:  *  - url   - The URL of the PDF.  *  - data  - A typed array with PDF data.  *  - httpHeaders - Basic authentication headers.  *  - password - For decrypting password-protected PDFs.  *  * @return {Promise} A promise that is resolved with {PDFDocumentProxy} object.  */ 

So a standard XMLHttpRequest(XHR) is used for retrieving the document. The Problem with this is that XMLHttpRequests do not support data: uris (eg. data:application/pdf;base64,JVBERi0xLjUK...).

But there is the possibility of passing a typed Javascript Array to the function. The only thing you need to do is to convert the base64 string to a Uint8Array. You can use this function found at https://gist.github.com/1032746

var BASE64_MARKER = ';base64,';  function convertDataURIToBinary(dataURI) {   var base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length;   var base64 = dataURI.substring(base64Index);   var raw = window.atob(base64);   var rawLength = raw.length;   var array = new Uint8Array(new ArrayBuffer(rawLength));    for(var i = 0; i < rawLength; i++) {     array[i] = raw.charCodeAt(i);   }   return array; } 

tl;dr

var pdfAsDataUri = "data:application/pdf;base64,JVBERi0xLjUK..."; // shortened var pdfAsArray = convertDataURIToBinary(pdfAsDataUri); PDFJS.getDocument(pdfAsArray) 
like image 89
Codetoffel Avatar answered Sep 24 '22 02:09

Codetoffel


According to the examples base64 encoding is directly supported, although I've not tested it myself. Take your base64 string (derived from a file or loaded with any other method, POST/GET, websockets etc), turn it to a binary with atob, and then parse this to getDocument on the PDFJS API likePDFJS.getDocument({data: base64PdfData}); Codetoffel answer does work just fine for me though.

like image 37
Uzer Avatar answered Sep 25 '22 02:09

Uzer