2014-06-18 35 views
8

Sono a conoscenza di una domanda simile a questa: Pdf.js: rendering a pdf file using a base64 file source instead of url. Questa domanda è stata meravigliosamente risolta da Codetoffel ma la mia domanda è diversa in quanto il mio PDF viene recuperato tramite una chiamata RESTful alla mia implementazione API Web. Mi spiego ...PDF.JS: rendering PDF utilizzando un oggetto ArrayBuffer o Blob anziché l'URL

In primo luogo, ecco un modo semplice per utilizzare pdf.js per aprire un file PDF tramite un URL:

PDFJS.getDocument("/api/path/to/my.pdf").then(function (pdf) { 
    pdf.getPage(1).then(function (page) { 
    var scale = 1; 
    var viewport = page.getViewport(scale); 
    var canvas = document.getElementById('the-canvas'); 
    var context = canvas.getContext('2d'); 
    canvas.height = viewport.height; 
    canvas.width = viewport.width; 
    page.render({canvasContext: context, viewport: viewport}); 
    }); 
}); 

Questa grande opera, ma sto usando angolare e la sua $resource servizio effettuare la richiesta per il PDF tramite la mia API Web RESTful. So che PDF.JS mi consente di sostituire l'URL come stringa nel metodo PDFJS.getDocument (sopra) con un oggetto DocumentInitParams, che è definito here. Utilizzando i DocumentInitParams oggetto funziona come segue:

var docInitParams = { 
    url: "/api/path/to/my.pdf", 
    httpHeaders: getSecurityHeaders(), //as needed 
    withCredentials: true 
}; 
PDFJS.getDocument(docInitParams).then(function (pdf) { 
    ... 
}); 

Questo funziona anche, ma funziona intorno alla mia angolare $resource richiedendo me per costruire l'URL api. Ma va bene perché PDFJS mi permette di dare i dati in formato PDF direttamente, invece di dare un URL al PDF, come segue:

var myPdf = myService.$getPdf({ Id: 123 }); 

//It's an Angular $resource, so there is a promise to be fulfilled... 
myPdf.$promise.then(function() { 
    var docInitParams = { 
     data: myPdf 
    }; 
    PDFJS.getDocument(docInitParams).then(function (pdf) { 
     ... 
    }); 
}); 

questo è quello che io non riesco a mettersi al lavoro. Posso dire al metodo myService.$gtPdf di restituire i dati come blob o come arraybuffer ma nessuno dei due funziona. Ho provato a convertire i dati restituiti da arraybuffer in uno Uint8Array, ma senza alcun risultato.

Non sono sicuro di cos'altro provare e potrei davvero usare un suggerimento.

Come posso ottenere i dati restituiti dal mio servizio per lavorare con PDFJS?

Grazie in anticipo.

risposta

17

Non stai passando i dati di risposta per pdf.js, ma un'istanza della risorsa:

var myPdf = myService.$getPdf({ Id: 123 }); 
myPdf.$promise.then(function() { 
    var docInitParams = { 
     data: myPdf 

Non hai mostrato il codice per $getPdf, ma credo che è qualcosa equivalente a

var myService = $resource('/foo', {}, {$getPdf:{responseType: 'arraybuffer'}}); 
var myPdf = myService.$getPdf(); 

per default, un AngularJS $resource considera la risposta come oggetto (deserializzazione da JSON) e copia le proprietà dall'oggetto all'istanza risorsa (myPdf nello snippet precedente).

Ovviamente, dal momento che la risposta è un buffer di array (o Blob, array tipizzato o qualsiasi altra cosa), questo non funzionerà. Uno dei modi per ottenere la risposta desiderata è quello di utilizzare transformResponse per avvolgere l'oggetto di risposta in un oggetto:

var myService = $resource('/foo', {}, { 
    $getPdf: { 
     responseType: 'arraybuffer', 
     transformResponse: function(data, headersGetter) { 
      // Stores the ArrayBuffer object in a property called "data" 
      return { data : data }; 
     } 
    } 
}); 
var myPdf = myService.$getPdf(); 
myPdf.$promise.then(function() { 
    var docInitParams = { 
     data: myPdf.data 
    }; 

    PDFJS.getDocument(docInitParams).then(function (pdf) { 
     // ... 
    }); 
}); 

O semplicemente le seguenti (evitate variabili locali non necessari):

myService.$getPdf().$promise.then(function(myPdf) { 
    PDFJS.getDocument({ 
     data: myPdf.data 
    }).then(function (pdf) { 
     // ... 
    }); 
}); 
+0

Grazie! Pensavo di aver bisogno di un esperto di PDF.JS per entrare, ma qualcuno con una migliore conoscenza angolare era davvero la chiave. Stavo già usando transformResponse ma non correttamente poiché stavo trattando la risorsa come se fosse la risposta. Una volta che lo hai indicato, tutto il resto è andato a posto. – witttness

+0

Ciao, cosa fai con il pdf in.quindi per caricare il documento nel viewer.html? – toddmo

+0

Se si desidera utilizzare questo con il viewer.html standard, quindi utilizzare 'PDFViewerApplication.open (myPdf);'. –