【问题标题】:Pdf.js: rendering a pdf file using a base64 file source instead of urlPdf.js:使用 base64 文件源而不是 url 呈现 pdf 文件
【发布时间】:2012-08-19 00:40:36
【问题描述】:

我正在尝试使用 pdf.js 从 pdf 呈现页面

通常,使用 url,我可以这样做:

PDFJS.getDocument("http://www.server.com/file.pdf").then(function getPdfHelloWorld(pdf) {
  //
  // Fetch the first page
  //
  pdf.getPage(1).then(function getPageHelloWorld(page) {
    var scale = 1.5;
    var viewport = page.getViewport(scale);

    //
    // Prepare canvas using PDF page dimensions
    //
    var canvas = document.getElementById('the-canvas');
    var context = canvas.getContext('2d');
    canvas.height = viewport.height;
    canvas.width = viewport.width;

    //
    // Render PDF page into canvas context
    //
    page.render({canvasContext: context, viewport: viewport});
  });
});

但在这种情况下,我的文件是 base64 而不是 url:

data:application/pdf;base64,JVBERi0xLjUKJdDUxdgKNSAwIG9iaiA8PAovTGVuZ3RoIDE2NjUgICAgICAKL0ZpbHRlciAvRmxhdGVEZWNvZGUKPj4Kc3RyZWFtCnjarVhLc9s2...

如何做到这一点?

【问题讨论】:

    标签: javascript pdf canvas base64 pdf.js


    【解决方案1】:

    来自源代码 http://mozilla.github.com/pdf.js/build/pdf.js

    /**
     * This is the main entry point for loading a PDF and interacting with it.
     * NOTE: If a URL is used to fetch the PDF data a standard XMLHttpRequest(XHR)
     * is used, which means it must follow the same origin rules that any XHR does
     * e.g. No cross domain requests without CORS.
     *
     * @param {string|TypedAray|object} source Can be an url to where a PDF is
     * located, a typed array (Uint8Array) already populated with data or
     * and parameter object with the following possible fields:
     *  - url   - The URL of the PDF.
     *  - data  - A typed array with PDF data.
     *  - httpHeaders - Basic authentication headers.
     *  - password - For decrypting password-protected PDFs.
     *
     * @return {Promise} A promise that is resolved with {PDFDocumentProxy} object.
     */
    

    因此使用标准 XMLHttpRequest(XHR) 来检索文档。 问题在于 XMLHttpRequests 不支持 data: uris (eg. data:application/pdf;base64,JVBERi0xLjUK...)。

    但是有可能将类型化的 Javascript 数组传递给函数。 您唯一需要做的就是将 base64 字符串转换为 Uint8Array。您可以使用https://gist.github.com/1032746中的此功能

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

    tl;dr

    var pdfAsDataUri = "data:application/pdf;base64,JVBERi0xLjUK..."; // shortened
    var pdfAsArray = convertDataURIToBinary(pdfAsDataUri);
    PDFJS.getDocument(pdfAsArray)
    

    【讨论】:

    • 那么是否可以获取 pdf 的二进制文件并使用 pdf.js 在 pdf 查看器中显示它
    • @Codetoffel 为我节省了几个小时
    • 干得好。但是,如果源是通过对数组缓冲区或 blob 的 RESTful 调用检索的 PDF 怎么办?我在这里发布了一个问题:stackoverflow.com/questions/24288221/…
    • 如果你在strict mode,不要忘记var之前的i = 0!我白白浪费了1个小时。 :)
    • 我得到了这个工作。我的回答是here
    【解决方案2】:

    According to the examplesbase64编码是直接支持的,虽然我自己没有测试过。获取您的 base64 字符串(从文件派生或使用任何其他方法加载,POST/GET、websockets 等),使用 atob 将其转换为二进制文件,然后将其解析为 PDFJS API 上的 getDocument,例如PDFJS.getDocument({data: base64PdfData}); Codetoffel 答案确实有效不过对我来说还不错。

    【讨论】:

    • 我已经使用带有PDFJS.getDocument({data: Buffer.from(pdf_base64, 'base64')})的nodejs包对其进行了测试
    【解决方案3】:

    使用 Accepted Answer 对 IE 进行检查并将 dataURI 转换为 UInt8Array; PDFJS 接受的表格

            Ext.isIE ? pdfAsDataUri = me.convertDataURIToBinary(pdfAsDataUri): '';
    
            convertDataURIToBinary: function(dataURI) {
              var BASE64_MARKER = ';base64,',
                base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length,
                base64 = dataURI.substring(base64Index),
                raw = window.atob(base64),
                rawLength = raw.length,
                array = new Uint8Array(new ArrayBuffer(rawLength));
    
              for (var i = 0; i < rawLength; i++) {
                array[i] = raw.charCodeAt(i);
              }
              return array;
            },

    【讨论】:

      猜你喜欢
      • 2014-08-08
      • 2015-11-07
      • 1970-01-01
      • 2020-07-28
      • 2014-01-24
      • 1970-01-01
      • 1970-01-01
      • 2021-03-13
      • 2021-03-27
      相关资源
      最近更新 更多