Документ pdf.js и зритель.js. Передача потока или blob в Средство просмотра

у меня возникли проблемы в поиске решения для этого: Я получаю PDF blob из поля SQL filestream, используя Javascript таким образом (это проект lightswitch)

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

у меня есть blob, и я даже могу преобразовать его в filestream или в base64("JVBERi0....."или" %PDF 1.6 ......", п.)

пока никаких проблем.

Теперь мне нужно отобразить его в окне просмотра. Я предпочитаю, чтобы зритель открывался в новом окне, но я открыт, чтобы как-то встроить его в свою страницу.

мне интересно, могу ли я напрямую передать blob или поток в Средство просмотра и отобразить документ. Я пробовал что-то вроде

PDFView.open(pdfAsArray, 0)

В этом случае во встроенном средстве просмотра ничего не происходит.

на pdfAsArray хорошо, так как я могу отобразить его, добавляя поток к холсту на той же странице. Я просто хочу отобразить средство просмотра, а не вставлять PDF в холст, возможно, в новое окно.

может ли кто-нибудь предоставить несколько строк кода о том, как достичь этого в JavaScript?

4 ответов


я использую PDFJS.version = '1.0.1040'; PDFJS.build = '997096f';

код, который работал для меня, чтобы загрузить данные base64 pdf, был следующим:

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

эта функция может быть функцией успеха обещания вызова api. То, что я делаю здесь, - это рендеринг pdf на элемент canvas myCanvas.

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

это показывает первую страницу PDF-файла, но не работает. Я понимаю, почему зритель желателен. Если я подключу это к viewer (зрителю.просмотр HTML.js) я буду редактировать ответ.

EDIT: Как подключить зрителя

1 на bower.json добавьте "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 измените глупый документ по умолчанию в :

var DEFAULT_URL = '';

4:

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

я, наконец, сделал PDFView.открытый метод работы. Теперь, если я вставляю средство просмотра на свою страницу и вызываю функцию open, как предложил Роб в первых 2 примерах, он работает.

для тех, кто ищет такого рода решение, я предоставляю некоторые строки кода здесь:

это код на моей главной странице Lightswitch.lsml.Яш Сценарии js (pdf.js, viewer и другие) ссылаются на главную html-страницу проекта Lightswitch(по умолчанию.html); я предполагаю, что это должно работать с любой другой html-страницей, не основанной на 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 
};

это функция 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;
}

то, что все еще не хватает, это возможность передать поток непосредственно зрителю.html-страница, чтобы открыть ее в новом окне и иметь отдельный пользовательский интерфейс, где сделать рендеринг.

этот код все еще не работает, так как я получил пустую просмотра документов внутри

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

похоже, что encodeURIComponent (url) не является передача зрителю хорошего объекта для загрузки в зритель. Есть идеи или предложения?


Если у вас есть типизированный массив (например,Uint8Array), то файл может быть открыт с помощью PDFView.open(typedarray, 0);.

если у вас Blob или


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'