本文使用的是 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下載和預覽的一些分享,哪裏有不對的,歡迎指正~