pdfjs

官网:PDF.js

官方demo:PDF.js viewer

安装使用

下载

项目引入

本文主要针对vue-cli4版本的文件

  • 在public文件夹下新建pdfjs文件夹,将下载好得 web 和 build 拷贝进去

修改源码配置(初步)

        因为pdf.js是不支持跨域文件加载的 直接加载是不会成功的。会报 “file origin doesnot match viewer”错误,所以需要把viewer.js文件内的抛出错误这一行报错注释掉

项目使用

初步运行demo

        既然是新框架,肯定想先玩玩试试效果,很简单,页面放一个iframe,然后src等于到viewer.html的public路径,直接(pdfjs/***)即可。

<iframe src="pdfjs/web/viewer.html" frameborder="0" class="pdf-window"></iframe>

效果就跟 官方demo一模一样。

正式面对项目需求

        我主要针对后台返回pdf文件流(base64/ArrayBuffer)情况,当然如果后台可以直接返回pdf地址那直接(file=后端返回的文件路径'/static/pdfjs/web/viewer.html?file=' + pdfVisitUrl)即可。

  • 打开viewer.html,添加如下代码(注意放在pdf.js引用之前):
<script type="text/javascript">
  var DEFAULT_URL = "";
  var pdfUrl = document.location.search.substring(1);
  if (null == pdfUrl || "" == pdfUrl) {
    var BASE64_MARKER = ';base64,'; //声明文件流编码格式
    var preFileId = "";
    var pdfAsDataUri = sessionStorage.getItem("_imgUrl"); //这里就是pdf文件的base64码,我是通过session传递base64的
    var pdfAsArray = convertDataURIToBinary(pdfAsDataUri);
    DEFAULT_URL = pdfAsArray;
    //编码转换
    function convertDataURIToBinary(dataURI) {
      //[RFC2045]中有规定:Base64一行不能超过76字符,超过则添加回车换行符。因此需要把base64字段中的换行符,回车符给去掉。
      var base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length;
      var newUrl = dataURI.substring(base64Index).replace(/[\n\r]/g, '');
      var raw = window.atob(newUrl); //这个方法在ie内核下无法正常解析。
      var rawLength = raw.length;
      //转换成pdf.js能直接解析的Uint8Array类型
      var array = new Uint8Array(new ArrayBuffer(rawLength));
      for (i = 0; i < rawLength; i++) {
        array[i] = raw.charCodeAt(i) & 0xff;
      }
      return array;
    }
  }
</script>

这段代码的意思是从session中读取存入的base64编码,然后展示。

  • 将读取pdf文件的固定路径修改为传入的变量

打开viewer.js,搜索defaultUrl替换为变量

此时所要修改的插件内容全部修改完成,接下来我们把base64存入session中,接下来有两种方式可以展示pdf:

  • 跳转到viewer.html中 。
sessionStorage.setItem('_imgUrl', interfaceUrl)
window.open('pdfjs/web/viewer.html')
  • 直接在组件页面嵌入即可。
js:

sessionStorage.setItem('_imgUrl', interfaceUrl)

this.interfaceUrl = interfaceUrl


页面:
<div v-if="interfaceUrl" class="homeLayout__right__pdf">
    <iframe :src="`pdfjs/web/viewer.html`" frameborder="0" class="pdf-window"></iframe>
</div>
  • 展示

  • 关于禁用打印下载,一定不要去直接注释,采用css,方式隐藏即可

viewer.html:272行左右

<!-- 禁用打印下载 -->
<button style="visibility: hidden;" id="print" class="toolbarButton hiddenMediumView" title="Print" tabindex="33" data-l10n-id="print">
     <span data-l10n-id="print_label">Print</span>
</button>

<button style="visibility: hidden;" id="download" class="toolbarButton hiddenMediumView" title="Download" tabindex="34" data-l10n-id="download">
     <span data-l10n-id="download_label">Download</span>
</button>

如何解码后台返回的对称加密的pdf文件流?

  • 定义解密方法,明确后台加密密钥以及偏移量
  • 首先下载
npm i -S crypto-js
  • 局部引用
import CryptoJS from "crypto-js";
  • 定义解密方法
// 对称解密
encryptDataJie (encStr) {
      // 此处key为16进制
      let key = '这是密钥'
      key = CryptoJS.enc.Utf8.parse(key)
      let iv = '这是偏移量'
      // 偏移量
      iv = CryptoJS.enc.Utf8.parse(iv)

      // base64处理
      const base64 = CryptoJS.enc.Base64.parse(encStr)
      const src = CryptoJS.enc.Base64.stringify(base64)
      // 解密方法
      const decryptedContent = CryptoJS.AES.decrypt(src,
        key, // 注意:后面这里最好使用 CryptoJS.format.Utf8.parse(key)
        {
          iv: iv,
          mode: CryptoJS.mode.CBC,
          padding: CryptoJS.pad.Pkcs7
        }
      )
      const decryptedContentStr = decryptedContent.toString(CryptoJS.enc.Utf8)
      return decryptedContentStr.toString()
}

报错注意事项:

  • 出现Error: Malformed UTF-8 data警告且获取不了数据的话,那就是后台没有指定base64解密及没有指定utf-8,与后台同步协调沟通让他们确认看看

参考

Logo

前往低代码交流专区

更多推荐