pdf.js 使用 base64 渲染为 PDF

标签 pdf.js

我被困在我的应用程序的最后一点,我应该以 PDF 格式显示用户表单,该表单在桌面浏览器上运行良好,因为它们内置了 pdf 查看器,但对于 Android/iOS 来说,它无法工作,因为缺少 pdf 查看器。

所以我尝试使用 PDF.js 来显示它,(说实话,这使用非常广泛,但缺乏文档),唯一的问题是我正在获取 Base64 格式的数据。 PDF.js 网站上有示例,展示了如何渲染 base64 数据,但它不是 PDF,对于将 PDF 显示为“PDF”的情况,我需要使用他们的“viewer.html”,但这并不需要 base64 数据?

我最近到的Pdf.js: rendering a pdf file using base64...堆栈溢出,但我不知道如何在 PDFJS.getDocument(pdfAsArray)? 之后使用它。

遇到的其他链接是 other link

我不想依赖 Google/第三方 PDF 查看器,因为我不知道他们会支持多久。

最佳答案

社区中没有关于此主题的端到端答案,因此我尝试在这里添加一些内容。 (也许对其他人有帮助)

好吧,PDF.js 是在浏览器中显示 PDF 的一种方式,特别是当您不想依赖安装的 PDF 插件时。就我而言,我的应用程序生成 PDF 格式的报告,并且可以在下载之前查看该报告,但在手持设备上由于缺少 PDF 查看器插件而无法工作。

在我的例子中,PDF 被发送到 base64 字符串中浏览,我可以用 <object src="base64-data"...></object> 显示 PDF。 。这与 Chrome/FF 上的魅力类似,但切换到移动 View 后就会停止工作。

<object type="application/pdf" id="pdfbin" width="100%" height="100%" title="Report.pdf">
   <p class="text-center">Looks like there is no PDF viewer plugin installed, try one of the below approach...</p>                
</object>

在上面的代码中,它将尝试显示 PDF 或回退到 <p>并显示错误消息。我当时计划添加 PDF 查看器,选择了 PDF.js,但无法显示它。 PDF.js 上使用 Base64 数据的一个示例展示了如何执行此操作,但这会将其呈现为图像而不是 PDF,并且我无法找到解决方案,因此问题是,这就是我所做的,

  1. 首先添加将base64转换为数组的JavaScript代码

  2. 转换为 blob 并使用 viewer.html用PDF.js打包的文件,将其显示为PDF

如果您想知道为什么使用 Base64 数据,那么答案很简单,我可以创建 PDF、阅读它、将数据发送到客户端并删除文件,我不必运行任何更清洁的服务/cron 作业删除生成的 PDF 文件

一些需要注意的事情

  1. Below code is using Flask + Jinja2, change the way base64 is read in html if you are using something else
  2. viewer.html needs to be changed to have required js & css files in proper location (by default their location is relative; you need them to be referred from static folder)
  3. viewer.js looks for pdf.worker.js in predefined location, change that in case its throwing error as above file not found.
  4. viewer.js might throw file origin does not match viewer error in that case as a quick fix comment the code which throws this error and see if that solves the issue (look for that error in viewer.js)
  5. I am not the author of below code, I have just put it together from different places.

现在看代码(这样当用户单击带有 id="open_id" 的按钮时将显示 PDF)


Jquery

var pdfDataX = '{{ base64Pdf }}';
var BASE64_MARKER = ';base64,';
PDFJS.workerSrc = "{{ url_for('static', filename='js/pdf.worker.js') }}";

$('#open_id').click(function() {        
    PDFJS.disableWorker = true;
    var pdfAsDataUri = "data:application/pdf;base64," + pdfDataX ;
    PDFJS.workerSrc = "{{ url_for('static', filename='js/pdf.worker.js') }}";

    // Try to show in the viewer.html

    var blob = base64toBlob(pdfDataX, 'application/pdf');
    var url = URL.createObjectURL(blob);
    var viewerUrl = "{{ url_for('static', filename='viewer.html') }}" + '?file=' + encodeURIComponent(url);
    $('#pdfViewer').attr('src', viewerUrl);

    // Finish

    var mdObj = $('#pdfbin');

    mdObj.hide();
    mdObj.attr('data', pdfAsDataUri);
    mdObj.show();

    $('#myModal').modal();
});

var base64toBlob = function(b64Data, contentType, sliceSize) {
    contentType = contentType || '';
    sliceSize = sliceSize || 512;

    var byteCharacters = atob(b64Data);
    var byteArrays = [];

    for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
        var slice = byteCharacters.slice(offset, offset + sliceSize);

        var byteNumbers = new Array(slice.length);
        for (var i=0; i<slice.length; i++) {
            byteNumbers[i] = slice.charCodeAt(i);
        }

        var byteArray = new Uint8Array(byteNumbers);

        byteArrays.push(byteArray);
    }
    var blob = new Blob(byteArrays, {type: contentType});
    return blob;
}

$('.save').click(function(e) {
    e.preventDefault();
    var blob = base64toBlob(pdfDataX, 'application/pdf');
    saveAs(blob, 'abcd.pdf');  // requires https://github.com/eligrey/FileSaver.js/
    return false;
});

HTML

<object type="application/pdf" id="pdfbin" width="100%" height="100%" title="Resume.pdf">
    <p class="text-center">Looks like there is no PDF viewer plugin installed, try one of the below approach...</p>
    <iframe id="pdfViewer" style="width: 100%; height: 100%;" allowfullscreen="" webkitallowfullscreen=""></iframe>                  
</object>

希望这对其他人将来有用。

关于pdf.js 使用 base64 渲染为 PDF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44215951/

相关文章:

javascript - 使用pdf.js嵌入PDF到网页

css - 性能问题 : Recalculating Styles takes 200ms in PDF. js

javascript - PDF.JS:使用 ArrayBuffer 或 Blob 而不是 URL 呈现 PDF

javascript - 带 blob 的 PDFjs 自定义文件名

javascript - 使用 pdf.js 在 pdf 到文本转换中将换行符显示为 `\n`

Firefox 在下载后破坏 pdf

ios - 显示具有将图片放在页面顶部的功能的 pdf

javascript - 将 Javascript 事件添加到使用 pdfJS 打开的 pdf

css - 为什么 scaleX 会导致绝对定位的元素向左移动?

javascript - 渲染pdf文件javascript