参考 https://github.com/FranckFreiburger/vue-pdf
1、 安装依赖
npm install pdfjs-dist -save
2、项目使用
创建pdf 预览的组件 pdf.vue
代码如下:
<template>
<div>
<el-carousel indicator-position="none" arrow="always" :autoplay="false" trigger="click">
<el-carousel-item
v-for="page in docPages"
:key="page"
>
<div class="page-container" ref="container">
<canvas
v-if="renderList.includes(page)"
:style="{
height: `${pageHeight}px`
}"
></canvas>
<div class="notice" v-if="show">{{ notice }}</div>
</div>
</el-carousel-item>
</el-carousel>
</div>
</template>
<script>
import pdfJS from "pdfjs-dist";
pdfJS.GlobalWorkerOptions.workerSrc =
"../../../node_modules/pdfjs-dist/build/pdf.worker.js";
export default {
props: {
url: {
type: String,
required: true
},
renderPages: {
type: Number,
default: 5
},
customScroll: {
type: Boolean,
default: false
},
offsetHeight: {
type: Number,
default: 0
}
},
data() {
return {
doc: null,
docPages: 0,
currentPage: 0,
pageHeight: 0,
renderList: [],
show: false,
notice: "",
timer: 0
};
},
watch: {
url: {
immediate: true,
handler() {
this.getPDFFile();
}
}
},
created() {
if (!this.customScroll) {
document.addEventListener("scroll", this.scroll);
}
},
beforeDestroy() {
document.removeEventListener("scroll", this.scroll);
},
methods: {
xiayiye() {
this.renderPage(3);
},
shangyiye() {
this.currentPage--;
},
getPDFFile() {
if (!this.url) return;
this.currentPage = 0;
let pdfTask = pdfJS.getDocument(this.url);
pdfTask.promise.then(pdf => {
this.doc = pdf;
this.docPages = pdf.numPages;
this.$nextTick(() => {
this.docPages && this.scrollToPage(1);
});
});
},
scrollToPage(pageNo) {
if (this.currentPage === pageNo) return;
this.currentPage = pageNo;
let list = [];
for (
let page = pageNo - this.docPages;
page <= pageNo + this.docPages;
page++
) {
list.push(page);
}
list = list.filter(page => page <= this.docPages && page >= 1);
this.$nextTick(() => {
this.renderList = list;
this.renderList.forEach(page => {
this.renderPage(page);
});
});
},
// 渲染page
renderPage(pageNo) {
this.doc.getPage(pageNo).then(page => {
let container = this.$refs.container[pageNo - 1];
if (!container) return;
let canvas = container.querySelector("canvas");
if (!canvas || canvas.__rendered) return;
let ctx = canvas.getContext("2d");
let dpr = window.devicePixelRatio || 1;
let bsr =
ctx.webkitBackingStorePixelRatio ||
ctx.mozBackingStorePixelRatio ||
ctx.msBackingStorePixelRatio ||
ctx.oBackingStorePixelRatio ||
ctx.backingStorePixelRatio ||
1;
let ratio = dpr / bsr;
let rect = container.getBoundingClientRect();
let viewport = page.getViewport({ scale: 1 });
let width = rect.width;
let height = (width / viewport.width) * viewport.height;
canvas.style.width = `${width}px`;
canvas.style.height = `${height}px`;
this.pageHeight = height;
canvas.height = height * ratio;
canvas.width = width * ratio;
ctx.setTransform(ratio, 0, 0, ratio, 0, 0);
page.render({
canvasContext: ctx,
viewport: page.getViewport({ scale: width / viewport.width })
});
canvas.__rendered = true;
});
},
scroll() {
this.checkRender(document.documentElement);
},
checkRender(el) {
if (!this.pageHeight) return;
let scrollTop = el.scrollTop;
if (el === document.documentElement) {
scrollTop =
el.scrollTop || window.pageYOffset || document.body.scrollTop;
}
let page = Math.floor((scrollTop - this.offsetHeight) / this.pageHeight);
page = Math.max(page, 1);
page = Math.min(page, this.docPages);
this.scrollToPage(page);
}
}
};
</script>
创建pdfPreview.vue
引入pdf 预览的组件 pdf.vue
<template>
<div>
<pdf-preview :url="url"></pdf-preview>
</div>
</template>
<script>
import pdfPreview from "./pdf.vue";
export default {
name: "pdf",
components: {
pdfPreview
},
data() {
return {
url: "../../../../static/java.pdf"
};
}
};
</script>
<style>
</style>