通过pdfjs实现在VUE-CLI中进行PDF预览,并禁用打印及下载功能
官网:PDF.js官方demo:PDF.js viewer下载本文主要针对vue-cli4版本的文件因为pdf.js是不支持跨域文件加载的 直接加载是不会成功的。会报 “file origin doesnot match viewer”错误,所以需要把viewer.js文件内的抛出错误这一行报错注释掉既然是新框架,肯定想先玩玩试试效果,很简单,页面放一个iframe,然后src等于到viewer.
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,与后台同步协调沟通让他们确认看看
参考
更多推荐
所有评论(0)