2012-08-23 10 views
53

Sto cercando di rendering di una pagina da un PDF con pdf.jspdf.js: il rendering di un file PDF utilizzando un file sorgente Base64 anziché URL

Normalmente, utilizzando un URL, posso fare questo:

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}); 
    }); 
}); 

Ma in questo caso, ho il file in Base64 piuttosto che un URL:

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

Come questo può essere fatto?

risposta

82

dal codice sorgente al 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. 
*/ 

Quindi un XMLHttpRequest standard (XHR) viene utilizzato per il recupero del documento. Il problema con questo è che XMLHttpRequests non supporta i dati: uris (ad esempio dati: application/pdf; base64, JVBERi0xLjUK ...).

Ma v'è la possibilità di passare un array JavaScript digitato alla funzione. L'unica cosa che devi fare è convertire la stringa base64 in un Uint8Array. È possibile utilizzare questa funzione trovato alla 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) 
+1

così sarà possibile recuperare il file binario di pdf e mostrarlo nel visualizzatore di pdf utilizzando pdf.js – dakait

+0

@Codetoffel mi fa risparmiare poche ore –

+1

Bel lavoro. Ma cosa succede se la fonte viene recuperata tramite una chiamata RESTful in un arraybuffer o blob? Ho postato una domanda su di esso qui: http://stackoverflow.com/questions/24288221/pdf-js-render-pdf-using-an-arraybuffer-or-blob-instead-of-url – witttness

0

Usata la risposta accettata di fare un controllo per IE e convertire il dataURI a UInt8Array; una forma accettata dal PDFJS

 Ext.isIE ? pdfAsDataUri = me.convertDataURIToBinary(pdfAsDataUri): ''; 
 

 
     convertDataURIToBinary: function(dataURI) { 
 
      var BASE64_MARKER = ';base64,', 
 
      base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length, 
 
      base64 = dataURI.substring(base64Index), 
 
      raw = window.atob(base64), 
 
      rawLength = raw.length, 
 
      array = new Uint8Array(new ArrayBuffer(rawLength)); 
 

 
      for (var i = 0; i < rawLength; i++) { 
 
      array[i] = raw.charCodeAt(i); 
 
      } 
 
      return array; 
 
     },

0

According to the examples codifica Base64 è supportato direttamente, anche se non ho provato io stesso. Prendete la stringa base64 (derivato da un file o caricato con qualsiasi altro metodo, POST/GET, WebSockets ecc), girare a un binario con atob, e poi analizzare questo per GetDocument sulle API PDFJS come PDFJS.getDocument({data: base64PdfData}); Codetoffel risposta funziona bene per me però.