vue pdf下载及预览(移动端)
本文使用的是 vue-pdf,其实还有其他的很多比如pdf.js,只不过觉得这个和vue结合了应该不用下载一堆东西,直接npm install就可以,所以采用vue-pdf来撰写pdf下载及预览。无论是预览还是下载,都需要安装vue-pdf1、安装vue-pdfnpm install --save vue-pdf2、在需要的组件里面引用import pdf from 'vu...
·
本文使用的是 vue-pdf,其实还有其他的很多比如pdf.js,只不过觉得这个和vue结合了应该不用下载一堆东西,直接npm install就可以,所以采用vue-pdf来撰写pdf下载及预览。
无论是预览还是下载,都需要安装vue-pdf
先看下效果:
1、安装vue-pdf
npm install --save vue-pdf
2、在需要的组件里面引用
import pdf from 'vue-pdf'
components: {pdf},
3、在需要的vue文件中引入vue-pdf,pdf引入以及使用的位置,如下图:
一、pdf下载
1、先在template中定义一个下载按钮,添加事件
<span @click.stop="gotoOption('downLoad', item['article'], index)"><i class="iconfont iconxiazai1"></i>下载</span>
2、methods中定义方法:
gotoOption (val, item, index) {
if (val === 'collect') {
this.collectReport(item, index)
} else if (val === 'downLoad') {
this.downloadWeekly(item['local_access_full-text-link'], item['article_article-title'], item['uuid'])
}
},
// 下载
downloadWeekly (url, pdfName, uuid) {
// 调用子组件的下载方法
this.downloadPDF(url, pdfName, uuid)
},
downloadPDF (url, fileName, uuid) {
const _this = this
fetch(url).then(function (response) {
if (response.ok) {
return response.arrayBuffer()
}
throw new Error('Network response was not ok.')
}).then(function (arraybuffer) {
let blob = new Blob([arraybuffer], {
type: `application/pdf;charset-UTF-8` // word文档为msword,pdf文档为pdf
})
let objectURL = URL.createObjectURL(blob)
let downEle = document.createElement('a')
let fname = fileName // 下载文件的名字
// let fname = `download` // 下载文件的名字
downEle.href = objectURL
downEle.setAttribute('download', fname)
document.body.appendChild(downEle)
downEle.click()
DownloadArticleList({ // 此处是调用接口,将下载的文件信息传给后台
uuid: uuid,
openid: _this.openid
}).then(res => {
if (res.data.errno === 0) {
alert('下载完成')
}
console.log('xiazai:', res.data)
})
}).catch(function (error) {
console.log('There has been a problem with your fetch operation: ', error.message)
})
},
以上就是pdf下载
二、pdf预览
一共有两种方法,一种是分页,还可以放大缩小,另一种是不分页,还未实现放大缩小
1、第一种是分页的pdf预览,也可以实现放大,代码如下:
<template>
<div class="collect_info">
<div class="score_header">
<div class="return__icon" @click="returnBack">
<i class="iconfont iconfanhui"></i>
</div>
<div class="title">下载详情</div>
</div>
<div class="pdf" v-show="fileType === 'pdf'">
<p class="arrow">
<!-- // 上一页-->
<span @click="changePdfPage(0)" class="turn" :class="{grey: currentPage===1}">上一页</span>
{{currentPage}} / {{pageCount}}
<!-- // 下一页-->
<span @click="changePdfPage(1)" class="turn" :class="{grey: currentPage===pageCount}">下一页</span>
</p>
<!-- // 自己引入就可以使用,这里我的需求是做了分页功能,如果不需要分页功能,只要src就可以了-->
<!-- // src需要展示的PDF地址-->
<!-- // 当前展示的PDF页码-->
<!-- // PDF文件总页码-->
<!-- // 一开始加载的页面-->
<!-- // 加载事件-->
<pdf :src="src" :page="currentPage"
@num-pages="pageCount=$event"
@page-loaded="currentPage=$event"
@loaded="loadPdfHandler">
</pdf>
</div>
</div>
</template>
<script>
import pdf from 'vue-pdf'
export default {
metaInfo: {
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width,initial-scale=1.0, maximum-scale=2.0, user-scalable=yes' }
]
},
components: {pdf},
data () {
return {
currentPage: 0, // pdf文件页码
pageCount: 0, // pdf文件总页数
fileType: 'pdf', // 文件类型
src: '', // pdf文件地址
}
},
computed: {
pdfInfo () { // 这个是路由跳转携带的关于pdf的信息,包含链接,链接是可以直接打开pdf文件的
return this.$route.query.pdfInfo
}
},
created () {
// 有时PDF文件地址会出现跨域的情况,这里最好处理一下
this.src = pdf.createLoadingTask(this.pdfInfo.url)
},
methods: {
returnBack () {
this.$router.push({name: 'myDownLoad'})
},
// 改变PDF页码,val传过来区分上一页下一页的值,0上一页,1下一页
changePdfPage (val) {
// console.log(val)
if (val === 0 && this.currentPage > 1) {
this.currentPage--
// console.log(this.currentPage)
}
if (val === 1 && this.currentPage < this.pageCount) {
this.currentPage++
// console.log(this.currentPage)
}
},
// pdf加载时
loadPdfHandler (e) {
this.currentPage = 1 // 加载的时候先加载第一页
}
}
}
</script>
<style lang="scss" scoped>
.collect_info {
height: 100%;
display: flex;
flex-direction: column;
/*background: #f8f8f8;*/
position: relative;
}
.score_header {
text-align: center;
letter-spacing: 0.2em;
position: relative;
font-size: 18px;
width: 100%;
background-color: rgb(0, 115, 231);
color: #fff;
height: 45px;
line-height: 45px;
flex: none;
z-index: 1;
}
.return__icon{
position: absolute;
margin-left: 15px;
}
.iconfanhui {
margin-top: 10px;
font-size: 20px;
}
.pdf {
text-align: center;
.arrow {
margin: 8px 0;
/*font-size: 14px;*/
}
.grey {
color: #9c9c9c;
}
}
</style>
pdf链接打开是这样的:
2、 第二种是不分页的不可以实现放大缩小,但是可以上下滚动
<template>
<div class="collect_info">
<div class="score_header">
<div class="return__icon" @click="returnBack">
<i class="iconfont iconfanhui"></i>
</div>
<div class="title">下载详情</div>
</div>
<div class="pdfIn" v-show="fileType === 'pdf'" ref="pdfView">
<div>
<pdf
v-for="i in numPages"
ref="pdfs"
:src="src"
:key="i"
:page="i"
>
</pdf>
</div>
</div>
</div>
</template>
<script>
import pdf from 'vue-pdf'
import BScroll from 'better-scroll'
export default {
metaInfo: {
meta: [
{ name: 'viewport', content: 'width=device-width,initial-scale=1.0, maximum-scale=2.0, user-scalable=yes' }
]
},
components: {pdf},
data () {
return {
fileType: 'pdf', // 文件类型
src: '', // pdf文件地址
numPages: 0, // 总页数
pdfScroll: null,
}
},
computed: {
pdfInfo () { // 路由携带的参数,包括pdf链接
return this.$route.query.pdfInfo
}
},
created () {
// 有时PDF文件地址会出现跨域的情况,这里最好处理一下
this.src = pdf.createLoadingTask(this.pdfInfo.url)
this.src.promise.then(pdf => {
this.numPages = pdf.numPages
})
this.init()
},
methods: {
returnBack () {
this.$router.push({name: 'myDownLoad'})
},
init () {
this.$nextTick(() => {
this.pdfScroll = new BScroll(this.$refs.pdfView, {
click: true
})
})
},
}
}
</script>
<style lang="scss" scoped>
.collect_info {
height: 100%;
display: flex;
flex-direction: column;
/*background: #f8f8f8;*/
position: relative;
}
.score_header {
text-align: center;
letter-spacing: 0.2em;
position: relative;
font-size: 18px;
width: 100%;
background-color: rgb(0, 115, 231);
color: #fff;
height: 45px;
line-height: 45px;
flex: none;
z-index: 1;
}
.return__icon{
position: absolute;
margin-left: 15px;
}
.iconfanhui {
margin-top: 10px;
font-size: 20px;
}
.pdfIn {
height: calc(100% - 50px);
overflow: hidden;
}
</style>
以上就是关于pdf下载和预览的一些分享,哪里有不对的,欢迎指正~
更多推荐
已为社区贡献7条内容
所有评论(0)