Pdf.js和viewer.js.将流或blob传递给查看器

  发布于 2023-01-06 16:50

我在寻找解决方案时遇到了麻烦:我以这种方式使用Javascript从SQL文件流字段中检索PDF blob(这是一个lightswitch项目)

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

我有blob,我甚至可以将其转换为文件流或base64("JVBERi0 ....."或"%PDF 1.6 ......"等)

到目前为止没问题.

现在我需要在观众中显示它.我更喜欢观众在新窗口中打开,但我愿意以某种方式将其嵌入到我的页面中.

我想知道我是否可以直接将blob或流传递给查看器并显示文档.我尝试过类似的东西

PDFView.open(pdfAsArray, 0)

在这种情况下,嵌入式查看器中没有任何反应.

pdfAsArray很好,因为我可以显示它将流附加到同一页面内的画布.我只想显示查看器,而不是将PDF嵌入画布,可能在新窗口中.

任何人都可以提供几行代码,如何在Javascript中实现这一点?

3 个回答
  • 我正在使用 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调用promise的成功函数.我在这里做的是将pdf渲染到canvas元素上myCanvas.

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

    这显示了pdf的第一页,但没有任何功能.我可以看到为什么观众是可取的.如果我把它连接到查看器(viewer.html/viewer.js),我将编辑我的答案.

    编辑:如何连接查看器

    1bower.json,添加"pdfjs-viewer": "1.0.1040"

    2 Html:

    <iframe id="pdfViewer" src="lib/pdfjs-viewer/web/viewer.html"  allowfullscreen="" webkitallowfullscreen=""></iframe>
    

    3更改文件中的愚蠢默认文档viewer.js:

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

    2023-01-06 16:53 回答
  • 我终于使PDFView.open方法起作用了.现在,如果我将查看器嵌入到我的页面中并调用open函数,正如Rob在前两个示例中所建议的那样,它可以工作.

    对于那些正在寻找这种解决方案的人,我在这里提供了一些代码:

    这是我的Lightswitch中的代码mainPage.lsml.js在Lightswitch项目的主html页面中引用了js脚本(pdf.js,viewer和Others)(Default.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;
    }
    

    仍然遗漏的是将流直接传递给viewer.html页面的可能性,以便在新窗口中打开它并具有单独的ui进行渲染.

    这个代码仍然无法工作,因为我有一个没有文档的空查看器

    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)没有向查看器传递加载到查看器中的好对象.有什么想法或建议吗?

    2023-01-06 16:53 回答
  • 如果你有一个类型化的数组(例如一个Uint8Array),那么可以使用打开文件PDFView.open(typedarray, 0);.

    如果您有一个Blob或一个File对象,那么在您可以查看之前,必须将数据转换为类型化数组:

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

    另一种方法是为Blob/File对象创建一个URL:

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

    如果PDF查看器与嵌入框架的网站的源相同,则您还可以通过将blob URL传递给查看器来查看PDF:

    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.
    

    2023-01-06 16:53 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有