Pdf.js e viewer.js. Passa un stream o un blob al visualizzatore

Ho difficoltà a trovare una soluzione per questo: recupero un blob PDF da un campo filestream SQL utilizzando Javascript in questo modo (è un progetto di interruttore a luce)

var blob = new Blob([screen.WebReportsPdfFilesStream.selectedItem.Pdf], { type: "application/pdf;base64" }); 

Ho il blob e posso anche convertirlo in un filestream o in base64 (“JVBERi0 …..” o “% PDF 1.6 ……”, ecc.)

Nessun problema finora.

Ora ho bisogno di visualizzarlo in un visualizzatore. Preferisco che lo spettatore apra in una nuova finestra, ma sono aperto a incorporarlo nella mia pagina in qualche modo.

Mi chiedo se posso passare direttamente il blob o il stream al visualizzatore e visualizzare il documento. Ho provato qualcosa di simile

 PDFView.open(pdfAsArray, 0) 

Nulla accade nel visualizzatore incorporato in questo caso.

Il pdfAsArray è buono poiché posso visualizzarlo aggiungendo il stream a una canvas all’interno della stessa pagina. Voglio solo visualizzare il visualizzatore, non incorporare il PDF in una canvas, possibilmente in una nuova finestra.

Qualcuno può fornire poche righe di codice su come ottenerlo in Javascript?

Sto usando PDFJS.version = '1.0.1040'; PDFJS.build = '997096f'; PDFJS.version = '1.0.1040'; PDFJS.build = '997096f';

Il codice che ha funzionato per ottenere i dati pdf di base64 caricati era questo:

 function (base64Data) { var pdfData = base64ToUint8Array(base64Data); PDFJS.getDocument(pdfData).then(function (pdf) { pdf.getPage(1).then(function (page) { var scale = 1; var viewport = page.getViewport(scale); var canvas = document.getElementById('myCanvas'); var context = canvas.getContext('2d'); canvas.height = viewport.height; canvas.width = viewport.width; page.render({ canvasContext: context, viewport: viewport }); }); }); function base64ToUint8Array(base64) { var raw = atob(base64); var uint8Array = new Uint8Array(raw.length); for (var i = 0; i < raw.length; i++) { uint8Array[i] = raw.charCodeAt(i); } return uint8Array; } } 

Questa funzione potrebbe essere la funzione di successo di una promise call api. Quello che sto facendo qui è il rendering del pdf su un elemento canvas myCanvas .

  

Questo mostra la prima pagina del pdf ma non ha funzionalità. Posso capire perché lo spettatore è desiderabile. Se ottengo questo collegato al visualizzatore (viewer.html / viewer.js), modificherò la mia risposta.

EDIT: come colbind il visualizzatore

1 In bower.json , aggiungi "pdfjs-viewer": "1.0.1040"

2 Html:

  

3 Cambia lo stupido documento predefinito nel file viewer.js :

var DEFAULT_URL = '';

4 controller:

 var pdfjsframe = document.getElementById('pdfViewer'); pdfjsframe.onload = function() { LoadPdfDocument(); }; $scope.myApiCallThatReturnsBase64PdfData.then( function(base64Data) { $scope.base64Data = base64Data; LoadPdfDocument(); }, function(failure) { //NotificationService.error(failure.Message); }); function LoadPdfDocument() { if ($scope.PdfDocumentLoaded) return; if (!$scope.base64Data) return; var pdfData = base64ToUint8Array($scope.base64Data); pdfjsframe.contentWindow.PDFViewerApplication.open(pdfData); $scope.PdfDocumentLoaded = true; } function base64ToUint8Array(base64) { var raw = atob(base64); var uint8Array = new Uint8Array(raw.length); for (var i = 0; i < raw.length; i++) { uint8Array[i] = raw.charCodeAt(i); } return uint8Array; } 

Finalmente ho fatto funzionare il metodo PDFView.open. Ora se incorporo il visualizzatore nella mia pagina e chiamo la funzione di apertura come Rob ha suggerito nei primi 2 esempi funziona.

Per coloro che sono alla ricerca di questo tipo di soluzione, fornisco alcune linee di codice qui:

Questo è il codice nel mio Lightswitch mainPage.lsml.js Gli script js (pdf.js, viewer e Altri) sono referenziati nella pagina html principale del progetto Lightswitch (Default.html); Presumo che dovrebbe funzionare con qualsiasi altra pagina HTML non basata su Lightswitch.

 myapp.MainPage.ShowPdf_execute = function (screen) { // Write code here. // Getting the stream from sql var blob = new Blob([screen.WebReportsPdfFilesStream.selectedItem.Pdf], { type: "application/pdf;base64" }); // Pass the stream to an aspx page that makes some manipulations and returns a response var formData = new FormData(); formData.tagName = pdfName; formData.append(pdfName, blob); var xhr = new XMLHttpRequest(); var url = "../OpenPdf.aspx"; xhr.open('POST', url, false); xhr.onload = function (e) { var response = e.target.response; var pdfAsArray = convertDataURIToBinary("data:application/pdf;base64, " + response); var pdfDocument; // Use PDFJS to render a pdfDocument from pdf array PDFJS.getDocument(pdfAsArray).then(function (pdf) { pdfDocument = pdf; var url = URL.createObjectURL(blob); PDFView.load(pdfDocument, 1.5) }) }; xhr.send(formData); // multipart/form-data }; 

Questa è la funzione convertDataURIToBinary

 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 (i = 0; i < rawLength; i++) { array[i] = raw.charCodeAt(i); } return array; } 

Ciò che manca ancora è la possibilità di passare lo stream direttamente alla pagina viewer.html per aprirlo in una nuova finestra e avere un ui separato dove effettuare il rendering.

Questo codice non funziona ancora da quando ho un visualizzatore vuoto senza documenti all'interno

 var blob = new Blob([screen.WebReportsPdfFilesStream.selectedItem.Pdf], { type: "application/pdf;base64" }); var url = URL.createObjectURL(blob); var viewerUrl = 'Scripts/pdfViewer/web/viewer.html?file=' + encodeURIComponent(url); window.open(viewerUrl); 

Sembra che encodeURIComponent (url) non stia passando al visualizzatore un buon object da caricare nel visualizzatore. Qualche idea o suggerimento?

Se hai un array tipizzato (ad es. Un Uint8Array ), il file può essere aperto usando PDFView.open(typedarray, 0); .

Se hai un object Blob o File , i dati devono essere convertiti in un array tipizzato prima di poterli visualizzare:

 var fr = new FileReader(); fr.onload = function() { var arraybuffer = this.result; var uint8array = new Uint8Array(arraybuffer); PDFView.open(uint8array, 0); }; fr.readAsArrayBuffer(blob); 

Un altro metodo consiste nel creare un URL per l’object Blob / File:

 var url = URL.createObjectURL(blob); PDFView.open(url, 0); 

Se PDF Viewer è ospitato nella stessa origine del tuo sito web che incorpora il frame, puoi anche visualizzare il PDF passando l’URL blob al visualizzatore:

 var url = URL.createObjectURL(blob); var viewerUrl = 'web/viewer.html?file=' + encodeURIComponent(url); // TODO: Load the PDF.js viewer in a frame or new tab/window. 
 var url = URL.createObjectURL(blob); var viewerUrl = 'web/viewer.html?file=' + encodeURIComponent(url); // TODO: Load the PDF.js viewer in a frame or new tab/window. //-- Abobe code opens a new window but with errors : 'Missing PDF // blob://http://server-addr:port/converted-blob'