小编最近接手的项目中,有个需求,前端显示后端返回的PDF格式的文件,经过小编两天的调研和试验,终于找到了一个比较好的插件方法,直接贴代码。
1、安装
npm i vue-pdf-signature --save-dev
2、pdfShow.vue
<template>
<div class="pdf-content">
<!-- 显示所有页 -->
<div class="all-pdf" v-if="isShowAll">
<pdf v-for="i in pageTotalNum" :key="i" :src="pdfUrl" :page="i"/>
</div>
<!-- 只显示第一页,进行翻页查看 -->
<div class="change-page-pdf" v-else>
<pdf ref="pdf"
:src="pdfUrl"
:page="currentPage"
@progress="loadedRatio=$event"
@page-loaded="pageLoaded($event)"
@num-pages="pageTotalNum=$event"
@link-clicked="page=$event"
/>
{{currentPage}}/{{pageTotalNum}}
<div class="btn-box">
<span class="prev-btn" @click.stop="changePdfPage('prev')">上一页</span>
<span class="next-btn" @click.stop="changePdfPage('next')">下一页</span>
</div>
</div>
</template>
<script>
import pdf from "vue-pdf-signature";
import CMapReaderFactory from "vue-pdf-signature/src/CMapReaderFactory";
export default {
props: {
//是否显示所有页
isShowAll: {
type: Boolean,
default: true,
},
},
components: {
pdf,
},
data() {
return {
pdfUrl: "/static/test/pdf", //pdf文件路径
currentPage: 1, //当前页码
pageTotalNum: 1, //总页数
loadedRatio: 0, //pdf是否已加载完成 0:未完成 1:完成
};
},
mounted() {
this.pdfTask(this.pdfUrl);
},
methods: {
/**
* pdf初始化
* @param {pdfUrl} string pdf路径 - 若为静态文件,需放在static文件夹下
*/
pdfTask(pdfUrl) {
const that = this;
//该方法可以显示合同类型pdf中的印章、签名等,但字体较小的文案则无法显示
var loadingTask = pdf.createLoadingTask(pdfUrl);
//该方法可以完整显示文案,但无法显示合同类型pdf中的印章、签名
var loadingTask = pdf.createLoadingTask({
url: pdfUrl,
CmapPacked: true,
CMapReaderFactory,
});
loadingTask.promise
.then((pdf) => {
that.pdfUrl = loadingTask;
that.pageTotalNum = pdf.numPages;
})
.catch((err) => {
console.log("加载失败", err);
});
},
/**
* pdf加载
*/
pageLoaded(e) {
this.currentPage = e;
},
/**
* 翻页
* @param {pageOperation} 翻页类型 prev:上一页 next:下一页
*/
changePdfPage(pageOperation) {
let page = this.currentPage;
if (pageOperation == "prev") {
if (page == 1) return false;
page--;
}
if (pageOperation == "next") {
if (page == this.pageTotalNum) return false;
page++;
}
this.currentPage = page;
},
},
};
</script>
<style lang="scss" scoped>
.pdf-content {
width: 100%;
.btn-box {
width: 100%;
display: flex;
justify-content: space-between;
span {
display: block;
width: 50%;
height: 44px;
text-align: center;
line-height: 44px;
color: #333;
background: #fff;
}
.next-btn {
color: #fff;
background: #fa5050;
}
}
}
</style>
注意:该插件实际是使用canvas进行绘制,若同一个页面使用PDF显示的同时又使用canvas进行绘制,自制的canvas绘制会存在无法绘制的情况,小编还未有方案解决。
综上所述,由于小编的项目中PDF格式文件中的内容必会出现印章和签名,且询问了很多大佬都无解,所以该插件方法也被pass掉了,最后决定还是由后端将PDF文件格式转换成图片来实现。虽然该插件方案存在问题,如果PDF文件中无印章、签名等元素,纯文案的话,该插件文案还是给力的,中文也可以显示正常哦,所以小编还是在此将方案代码分享一下,希望对需要的童鞋有帮助。