vue项目中预览pdf文件
一、利用浏览器自带的预览pdf// [pdfUrl] 获取pdf地址 eg:http://mozilla.github.io/pdf.js/web/compressed.tracemonkey-pldi-09.pdf<iframe ref="mainiframe" :src="pdfUrl" style="height:100%;width:100%" ></iframe...
一、利用浏览器自带的预览pdf
// [pdfUrl] 获取pdf地址 eg:http://mozilla.github.io/pdf.js/web/compressed.tracemonkey-pldi-09.pdf
<iframe ref="mainiframe" :src="pdfUrl" style="height:100%;width:100%" ></iframe>
二、vue项目中使用pdf.js预览pdf文件
首先肯定是导入插件,我是从官网直接下载,链接:点击打开链接,注意放在static文件目录下,
这里面有核心的pdf.js和pdf.worker.js,以及展示pdf的viewer页面把它作为静态资源来编译,基本想要的build和web这两个重要文件夹的东西都正常编译。当然你可以可以npm install一下,整个文件放在static目录下的不好地方就是打包会很大哟(当然你可以选择性的删除里面的文件,比如绝大部分语言包)。目录结构放一下
其实就可以直接用的,网上很多,viewer.js 里的
代表着文件路径,如果你项目中有个pdf文件,那直接相对路径就可以在页面预览,如果使用远程预览,其实这里的路径会被覆盖,你删不删除它自带的路径都不会影响你的远程预览,so我今天说的是远程预览(服务器端url预览),pdf.js也提供了一种方法,
用file= 的方式也可以打开哟,放在页面上使用,我是iframe进行嵌套
用这种方式必不可少的是跨域问题,你存储文件的服务器路径会和项目产生跨域,我的解决办法是,让后台返回流的形式返回文件,后台代码案例:
注意:
1 pdf.js是不支持跨域文件加载的 直接加载是不会成功的。会报 “file origin doesnot match viewer”错误。 所以我们得改变一下源码
把这句警告直接注释就行了
2 file参数中默认只允许传简单路径比如:http://www.a.com/file.php. 如果你要浏览的pdf路径为http://www.a.com/file.php?id=2001。 这时候直接传入的话会解析出错, 因为pdf.js无法判断id=2001是viewer.html的参数呢还是file.php的参数
这告诉我们 url必须进行encode编码 把参数file后传入的动态参数中特殊字符转义:
这里又会有两种方法:
encodeURI() 把字符串编码为 URI
encodeURIComponent() 把字符串编码为 URI 组件
发现 encodeURI不会对:/?&等uri中起分割作用的字符进行编码;
encodeURIComponent则会。
所以必须选择 encodeURIComponent 进行对url的编码
举例:
这样如此就ok了
3
如果 后台返回给前台的流的url形式 是
https://uat.hjl.hscf.com/api/esm/v1/contractTemplates/load?id=13&access_token=a33e14ef6aba87b593b1aac31e3d97bb
这样pdf.js插件是无法识别的,所以的在最后加上 &.pdf 来骗过插件
效果图
注:注意查看服务器返回流,token会失效,你测试的时候会报错。另外需要处理页面重定向。
最后补上官方demo链接:vue-pdf.js-demo
原文链接: vue项目中使用pdf.js预览pdf文件
三、利用pdf.js封装vue组件在vue中实现在线pdf查看
1. 安装
cnpm install --save pdfjs-dist@2.0.943
2. 以组件的形式新建一个页面,CPdf.vue
然后按照需求去进行页面布局,我做的功能是一个合同查看功能,html如下:
<template>
<div class="cpdf" id="cpdf">
<top-normal-bar normalTitle="合同查看"></top-normal-bar>
<div class="center">
<div class="contor">
<button @click="prev">上一页</button>
<button @click="next">下一页</button>
<span>Page: <span v-text="page_num"></span> / <span v-text="page_count"></span></span>
<button @click="addscale" >加</button>
<button @click="minus" >减</button>
<button id="prev" @click="closepdf">关闭</button>
</div>
<canvas class="canvasstyle" id="the-canvas"></canvas>
</div>
</div>
</template>
样式如下:
<style type="text/less" lang="less" rel="stylesheet/less">
.cpdf {
position: fixed;
top: 0;
left: 0;
background-color: rgba(0, 0, 0, .5);
width: 100%;
height: 100%;
z-index: 99999;
display: flex;
justify-content: center;
align-items: center;
.center {
text-align: center;
height: 100%;
overflow: auto;
padding-top: 20px;
.contor {
margin-bottom: 10px;
}
}
}
</style>
然后js如下:
<script>
import PDFJS from 'pdfjs-dist'
export default {
name: 'c-pdf',
props: ['pdfurl'],
data() {
return {
pdfDoc: null, //pdfjs 生成的对象
pageNum: 1,//
pageRendering: false,
pageNumPending: null,
scale: 1,//放大倍数
page_num: 0,//当前页数
page_count: 0,//总页数
maxscale: 2,//最大放大倍数
minscale: 0.8//最小放大倍数
}
},
methods: {
renderPage(num) { //渲染pdf
let vm = this;
this.pageRendering = true;
let canvas = document.getElementById('the-canvas')
// Using promise to fetch the page
this.pdfDoc.getPage(num).then(function(page) {
var viewport = page.getViewport(vm.scale);
//alert(vm.canvas.height)
canvas.height = viewport.height;
canvas.width = viewport.width;
// Render PDF page into canvas context
var renderContext = {
canvasContext: vm.ctx,
viewport: viewport
};
var renderTask = page.render(renderContext);
// Wait for rendering to finish
renderTask.promise.then(function() {
vm.pageRendering = false;
if(vm.pageNumPending !== null) {
// New page rendering is pending
vm.renderPage(vm.pageNumPending);
vm.pageNumPending = null;
}
});
});
vm.page_num = vm.pageNum;
},
addscale() {//放大
if(this.scale >= this.maxscale) {
return
}
this.scale += 0.1;
this.queueRenderPage(this.pageNum)
},
minus() {//缩小
if(this.scale <= this.minscale) {
return
}
this.scale -= 0.1;
this.queueRenderPage(this.pageNum)
},
prev() {//上一页
let vm = this
if(vm.pageNum <= 1) {
return;
}
vm.pageNum--;
vm.queueRenderPage(vm.pageNum);
},
next() {//下一页
let vm = this;
if(vm.pageNum >= vm.page_count) {
return;
}
vm.pageNum++;
vm.queueRenderPage(vm.pageNum);
},
closepdf() {//关闭PDF
this.$emit('closepdf')
},
queueRenderPage(num) {
if(this.pageRendering) {
this.pageNumPending = num;
} else {
this.renderPage(num);
}
}
},
computed: {
ctx() {
let id = document.getElementById('the-canvas')
return id.getContext('2d');
}
},
mounted() {
let vm = this;
PDFJS.getDocument(vm.pdfurl).then(function(pdfDoc_) { //初始化pdf
vm.pdfDoc = pdfDoc_;
vm.page_count = vm.pdfDoc.numPages;
vm.renderPage(vm.pageNum);
});
}
}
</script>
这样一个pdf查看的组件就封装好了,只要按需在使用到此组件的页面引入就可以了。
引入:
import CPdf from "../components/commons/pdf/CPdf";
使用:
<c-pdf :pdfurl="pdfUrl"></c-pdf>
注释:pdfurl为pdf文件的地址,按照自己的地址引入,就可以正常显示pdf了。
data() {
return {
pdfUrl:"http://mozilla.github.io/pdf.js/web/compressed.tracemonkey-pldi-09.pdf"
}
}
原文链接:利用pdf.js封装vue组件在vue中实现在线pdf查看
四、vue-pdf实现pdf文件在线预览
查看链接:vue-pdf实现pdf文件在线预览
更多推荐
所有评论(0)