<template>
|
<GlobalWindow
|
:title="title"
|
width="100%"
|
:visible.sync="visible"
|
:confirm-working="isWorking"
|
@confirm="confirm"
|
>
|
<div class="pdfView">
|
<div class="show">
|
<!--分页显示-->
|
<pdf
|
ref="pdf"
|
:src="pdfUrl"
|
:page="pageNum"
|
:rotate="pageRotate"
|
@password="password"
|
@progress="loadedRatio = $event"
|
@loaded="onLoadSuccess"
|
@page-loaded="pageLoaded($event)"
|
@num-pages="pageTotalNum = $event"
|
@error="pdfError($event)"
|
@link-clicked="page = $event"
|
>
|
</pdf>
|
</div>
|
<div class="pdf_footer">
|
<div class="info">
|
<div>当前页数/总页数:{{ pageNum }}/{{ pageTotalNum }}</div>
|
<!-- <div>进度:{{ loadedRatio }}</div> -->
|
<!-- <div>页面加载成功: {{ curPageNum }}</div> -->
|
</div>
|
</div>
|
</div>
|
<template v-slot:footer>
|
<el-button-group>
|
<el-button type="primary" icon="el-icon-arrow-left" style="border-radius: 30px 0 0 30px" @click.stop="prePage">上一页</el-button>
|
<el-button type="primary" @click.stop="nextPage" style="border-radius: 0 30px 30px 0">下一页<i class="el-icon-arrow-right el-icon--right"></i></el-button>
|
</el-button-group>
|
<el-button-group style="margin-left: 30px">
|
<el-button type="primary" style="border-radius: 30px 0 0 30px" @click="scaleD">放大</el-button>
|
<el-button type="primary" style="border-radius: 0 30px 30px 0" @click="scaleX">缩小</el-button>
|
</el-button-group>
|
<el-button-group style="margin-left: 30px">
|
<el-button type="primary" style="border-radius: 30px 0 0 30px" @click="download(pdfUrl)">下载</el-button>
|
<el-button @click="visible=false" style="border-radius: 0 30px 30px 0" >关闭</el-button>
|
</el-button-group>
|
</template>
|
</GlobalWindow>
|
</template>
|
|
<script>
|
import BaseOpera from '@/components/base/BaseOpera'
|
import GlobalWindow from '@/components/common/GlobalWindow'
|
import pdf from 'vue-pdf'
|
export default {
|
name: 'OperaPdsViewerWindow',
|
extends: BaseOpera,
|
components: {
|
GlobalWindow,
|
pdf
|
},
|
data () {
|
return {
|
pdfUrl: '',
|
// 总页数
|
pageTotalNum: 1,
|
// 当前页数
|
pageNum: 1,
|
// 加载进度
|
loadedRatio: 0,
|
// 页面加载完成
|
curPageNum: 0,
|
// 放大系数 默认百分百
|
scale: 100,
|
// 旋转角度 ‘90’的倍数才有效
|
pageRotate: 0,
|
// 单击内部链接时触发 (目前我没有遇到使用场景)
|
page: 0,
|
// 当前页数
|
numPages: 1,
|
// 预览路径
|
localUrl: '',
|
loading: true
|
}
|
},
|
methods: {
|
open (title, target) {
|
this.pdfUrl = target
|
this.title = title
|
this.localUrl = ''
|
this.localUrl = this.pdfUrl
|
console.log(this.pdfUrl)
|
const loadingTask = pdf.createLoadingTask(this.localUrl)
|
loadingTask.promise.then(pdf => {
|
this.numPages = pdf.numPages
|
this.loading = false
|
}).catch((err) => {
|
this.$message.error('文件加载失败,可尝试下载文件查看!')
|
})
|
this.visible = true
|
},
|
onLoadSuccess (pdf) {
|
// PDF加载成功后,可以将初始页码设置为第一页
|
this.pageNum = 1
|
},
|
download (url) {
|
const link = document.createElement('a')
|
// 这里是将链接地址url转成blob地址,
|
fetch(url)
|
.then((res) => res.blob())
|
.then((blob) => {
|
link.href = URL.createObjectURL(blob)
|
// 下载文件的名称及文件类型后缀
|
link.download = this.title
|
document.body.appendChild(link)
|
link.click()
|
// 在资源下载完成后 清除 占用的缓存资源
|
window.URL.revokeObjectURL(link.href)
|
document.body.removeChild(link)
|
})
|
},
|
// 下载PDF
|
fileDownload (data, fileName) {
|
const blob = new Blob([data], {
|
// type类型后端返回来的数据中会有,根据自己实际进行修改
|
type: 'application/pdf'
|
})
|
const filename = fileName || 'pdf.pdf'
|
if (typeof window.navigator.msSaveBlob !== 'undefined') {
|
window.navigator.msSaveBlob(blob, filename)
|
} else {
|
var blobURL = URL.createObjectURL(blob)
|
// 创建隐藏<a>标签进行下载
|
var tempLink = document.createElement('a')
|
tempLink.style.display = 'none'
|
tempLink.href = blobURL
|
tempLink.setAttribute('download', filename)
|
if (typeof tempLink.download === 'undefined') {
|
tempLink.setAttribute('target', '_blank')
|
}
|
document.body.appendChild(tempLink)
|
tempLink.click()
|
document.body.removeChild(tempLink)
|
window.URL.revokeObjectURL(blobURL)
|
}
|
},
|
// 打印
|
pdfPrintAll () {
|
this.$refs.pdf.print()
|
},
|
// 放大
|
scaleD () {
|
this.scale += 5
|
this.$refs.pdf.$el.style.width = parseInt(this.scale) + '%'
|
},
|
|
// 缩小
|
scaleX () {
|
// scale 是百分百展示 不建议缩放
|
if (this.scale == 100) {
|
return
|
}
|
this.scale += -5
|
console.log(parseInt(this.scale) + '%')
|
this.$refs.pdf.$el.style.width = parseInt(this.scale) + '%'
|
},
|
// 切换上一页
|
prePage () {
|
var p = this.pageNum
|
p = p > 1 ? p - 1 : this.pageTotalNum
|
this.pageNum = p
|
},
|
// 切换下一页
|
nextPage () {
|
var p = this.pageNum
|
p = p < this.pageTotalNum ? p + 1 : 1
|
this.pageNum = p
|
},
|
// pdf 有密码 则需要输入秘密
|
password (updatePassword, reason) {
|
updatePassword(prompt('password is "test"'))
|
console.log('...reason...')
|
console.log(reason)
|
console.log('...reason...')
|
},
|
// 页面加载成功 当前页数
|
pageLoaded (e) {
|
console.log('pageLoaded', e)
|
this.$emit('current', e)
|
this.curPageNum = e
|
},
|
// 异常监听
|
pdfError (error) {
|
console.error('异常监听', error)
|
}
|
// getNumPages() {
|
// let loadingTask = pdf.createLoadingTask(this.pdfUrl);
|
// loadingTask.promise.then(pdf => {
|
// this.numPages = pdf.numPages;
|
// console.log('this.numPages', this.numPages)
|
// }).catch((err) => {
|
// console.error('pdf加载失败')
|
// })
|
// },
|
}
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
.pdfView {
|
padding: 20px;
|
.show {
|
overflow: auto;
|
margin: auto;
|
max-width: 100%;
|
//height: 80vh;
|
max-height: 100%;
|
border: 2px solid #eee;
|
border-radius: 6px;
|
background-color: #eeeeee;
|
// 滚动条样式
|
&::-webkit-scrollbar {
|
width: 10px;
|
}
|
&::-webkit-scrollbar-thumb {
|
background-color: #999;
|
border-radius: 6px;
|
}
|
&::-webkit-scrollbar-track {
|
background-color: transparent;
|
border-radius: 6px;
|
}
|
}
|
.pdf_footer {
|
position: fixed;
|
bottom: 10px;
|
font-size: 14px;
|
//left: 0;
|
right: 50px;
|
text-align: right;
|
//width: 50%;
|
padding: 10px 0;
|
background-color: rgba(255, 255, 255, 0.5);
|
.info {
|
display: flex;
|
flex-wrap: wrap;
|
justify-content: space-around;
|
div {
|
//width: 30%;
|
}
|
}
|
.operate {
|
margin: 10px 0 0;
|
display: flex;
|
flex-wrap: wrap;
|
justify-content: space-between;
|
div {
|
// width: 80px;
|
text-align: center;
|
font-size: 15px;
|
}
|
.btn {
|
cursor: pointer;
|
margin: 5px 10px;
|
width: 120px;
|
border-radius: 10px;
|
padding: 5px;
|
color: #fff;
|
background-color: #3dcbbc;
|
}
|
}
|
}
|
}
|
</style>
|