最近vue项目中遇到预览pdf出现乱码问题,尝试了各种办法受尽折磨,以此记录一下使用的几种方法
1.使用pdfjs-dist 插件,通过iframe标签显示
首先 npm install pdfjs-dist --save
npm直接下载插件 npm install --save pdfjs-dist@2.0.943,@2.0.943这是指定版本号,不需要指定版本的就不需要带,下载后在使用的页面直接引入。

然后直接设置pdf路径就可以直接展示,downloadurl 是插件中的viewer.html地址,resfile是文件下载地址,到此就能正常预览pdf,组件功能也很多,如需要额外的功能也可以在viewer.js自行修改

2.使用vue-pdf插件
执行下面命令下载插件(vue-pdf是基于pdfjs-dist),并修改pacakge.json文件
npm i pdfjs-dist@2.5.207 --save
npm i vue-pdf@4.2.0 --save
"dependencies": {
"pdfjs-dist": "2.5.207",
"vue-pdf": "4.2.0",
}在使用的页面中直接引入插件,标签为<pdf>就可以,路径赋值同第一种方法

3.第三种方法使用了pdfjs-dist插件,通过url实现pdf转图片显示
引入需要的插件pdfjs-dist,workersrc(具体功能可以百度,没搞明白)

本地文件url:

通过url转换blob类型,然后转为base64,这块可以直接拿去用,getday()方法可以换成自己想要的文件名,这个方法转成base64后是包含前面类型的,又处理了一下,看个人需求
filelinktostreamdownload(url) {
let filename = this.getday()
let reg = /^([hh][tt]{2}[pp]:\/\/|[hh][tt]{2}[pp][ss]:\/\/)(([a-za-z0-9-~]+).)+([a-za-z0-9-~\/])+$/
if (!reg.test(url)) {
throw new error('传入参数不合法,不是标准的文件链接')
} else {
let xhr = new xmlhttprequest()
xhr.open('get', url, true)
xhr.setrequestheader('content-type', `application/pdf;charset-utf-8`)
xhr.responsetype = 'blob'
let that =this
xhr.onload = function() {
if (this.status == 200) {
//接受二进制文件流
var blob = this.response
// that.downloadexportfile(blob, filename);
that.blobtobase64(blob).then(res => {
// blob转base64
let basearr = res.split(',');
that.showpdf(basearr[1]);
})
}
}
xhr.send()
}
},
//blob类型转base64
blobtobase64(blob) {
return new promise((resolve, reject) => {
const filereader = new filereader();
filereader.onload = (e) => {
resolve(e.target.result);
};
// readasdataurl
filereader.readasdataurl(blob);
filereader.onerror = () => {
reject(new error('blobtobase64 error'));
};
});
},
getday() {
let time = new date(),
year = time.getfullyear(),
month = time.getmonth() + 1,
day = time.getdate(),
timestem = time.gettime()
return `${year}/${month}/${day}/${timestem}.pdf`
},拿到base64后,开始转图片处理:这个原理这里不多说了,也是照搬的, 如果pdfjs.getdocument()获取不到pdf对象,可以考虑一下版本问题(@2.2.228亲测好用)
async showpdf(base64val) {
let pdflist = document.queryselector('.pdflist') //通过queryselector选择dom节点,使用document.getelementbyid()也一样
let base64 = base64val //获得bas464编码
let decodedbase64 = window.atob(base64) //使用浏览器自带的方法解码
let pdfcurrent = await pdfjs.getdocument({data: decodedbase64}) //返回一个pdf对象
let pages = pdfcurrent.numpages //声明一个pages变量等于当前pdf文件的页数
for (let i = 1; i <= pages; i++) { //循环页数
let canvas = document.createelement('canvas')
let page = await pdfcurrent.getpage(i) //调用getpage方法传入当前循环的页数,返回一个page对象
let scale = 1;//缩放倍数,1表示原始大小
let viewport = page.getviewport(scale);
let context = canvas.getcontext('2d'); //创建绘制canvas的对象
canvas.height = viewport.height; //定义canvas高和宽
canvas.width = viewport.width;
let rendercontext = {
canvascontext: context,
viewport: viewport
};
await page.render(rendercontext)
canvas.classname = 'canvas' //给canvas节点定义一个class名,这里我取名为canvas
pdflist.appendchild(canvas) //插入到pdflist节点的最后
}
},通过这个方法亲测可以成功转图片,但是依旧没解决图片乱码问题

4.直接通过iframe标签
页面标签

还是通过转码,创建下载链接,直接给地址赋值皆可以了,#toolbar = 0 设置工具栏不显示

我这块需求是不能下载,只能打印,所以隐藏了工具栏,新增了打印按钮,最开始想的是直接window.print()方法打印页面,先看效果

只打印pdf界面右侧的小图(没搞懂),然后决定使用print-js打印插件,还是npm install--save print-js 先下载插件
在需要的页面直接引入

用法很简单,按钮绑定

直接用就可以,直接把地址附上,type是pdf类型就可以了

到这就实现了预览,打印功能,但还没找到获取打印页面按钮的方法,有知道的可以交流。
期间还涉及到了vue父窗口,子窗口通信的问题,碰到同样问题的可以看一下,附上图片
父页面

子页面调用

地址如下
总结
到此这篇关于vue通过url方式展示pdf的几种方法的文章就介绍到这了,更多相关vue url方式展示pdf内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论