PDF.js et le spectateur.js. Passer un flux ou un blob au spectateur

j'ai du mal à trouver une solution pour ça: Je récupère un blob PDF à partir D'un champ de FILESTREAM SQL en utilisant Javascript de cette façon (c'est un projet lightswitch)

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

j'ai le blob et je peux même le convertir en filestream ou en base64 ("Jvberio....."ou" %PDF 1.6 ......", etc.)

Pas de problème jusqu'à présent.

maintenant je dois l'afficher dans un visualiseur. Je préfère le spectateur à ouvrir dans une nouvelle fenêtre, mais je suis ouvert à l'intégrer dans ma page en quelque sorte.

je me demande si je peux passer directement le blob ou le flux au spectateur et afficher le document. J'ai essayé quelque chose comme

PDFView.open(pdfAsArray, 0)

Rien ne se passe dans le visualiseur incorporé dans ce cas.

pdfAsArray est bon puisque je peux l'afficher en ajoutant les flux vers une toile dans la même page. Je veux juste afficher le visualiseur, pas intégrer le PDF dans une toile, peut-être dans une nouvelle fenêtre.

quelqu'un Peut-il fournir quelques lignes de code sur la façon de réaliser cela en Javascript?

21
demandé sur Michael Gaskill 2014-07-02 19:58:21

4 réponses

j'utilise PDFJS.version = '1.0.1040'; PDFJS.build = '997096f';

Le code qui a fonctionné pour moi d'obtenir base64 pdf données chargées était ceci:

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

cette fonction pourrait être la fonction de succès d'une promesse d'appel api. Ce que je fais ici c'est rendre le pdf sur un élément de toile myCanvas.

<canvas id="myCanvas"></canvas>

ceci montre la première page du pdf mais n'a aucune fonctionnalité. Je vois pourquoi le spectateur est désirable. Si je l'accroche au spectateur (viewer.HTML / viewer.js) je vais modifier mon réponse.

EDIT: Comment faire pour accrocher le spectateur

1bower.json, ajouter "pdfjs-viewer": "1.0.1040"

2 Html:

<iframe id="pdfViewer" src="lib/pdfjs-viewer/web/viewer.html" style="width: 100%; height: 700px;" allowfullscreen="" webkitallowfullscreen=""></iframe>

3 changez le document stupide par défaut dans le viewer.js fichier:

var DEFAULT_URL = '';

4 Contrôleur:

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;
}
18
répondu toddmo 2015-10-13 19:02:25

j'ai finalement fait le PDFView.ouvrir méthode de travail. Maintenant, si j'intègre le visualiseur dans ma page et que J'appelle la fonction open comme Rob l'a suggéré dans les deux premiers exemples, cela fonctionne.

pour ceux qui recherchent ce genre de solution, je fournis quelques lignes de code ici:

c'est le code de ma page principale de commutateur lumineux.lsml.js Les scripts js (en format pdf.js, viewer et autres) sont référencés dans la page html principale du projet Lightswitch (par défaut.html); je suppose que cela devrait fonctionner avec toute autre page html non basée sur 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 
};

Ceci est la fonction 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;
}

ce qui manque encore, c'est la possibilité de passer le flux directement au spectateur.page html afin de l'ouvrir dans une nouvelle fenêtre et avoir une interface utilisateur où faire le rendu.

ce code ne fonctionne toujours pas puisque j'ai un visualiseur vide sans document à l'intérieur

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

ressemble à l'encodeURIComponent (url) n'est pas passer au spectateur un bon objet à charger dans la visionneuse. Toute idée ou suggestion?

9
répondu Efrael 2014-07-04 09:25:17

Si vous avez un tableau dactylographié (par exemple un Uint8Array), alors le fichier peut être ouvert en utilisant PDFView.open(typedarray, 0);.

Si vous avez un Blob ou File objet, les données doit être converti en un tableau typé avant de pouvoir l'afficher:

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

une autre méthode consiste à créer une URL pour l'objet Blob/File:

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

si le visualiseur PDF est hébergé au origine comme votre site web qui intègre le cadre, alors vous pouvez également voir le PDF par passage de la goutte d'URL pour le spectateur:

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.
8
répondu Rob W 2014-07-03 08:43:35
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' 
3
répondu Gaurav Kumar Jha 2015-05-19 07:30:24