使用 fetch 获取pdf 的buffer 流,然后使用 pdfjs 获取每一页的数据,从而绘制在 canvas 上
文件列表
- pdf.js
- pdf.worker.js
在 index.html 上引入pdd.js,可以使用 cdn 链接,也可以使用本地文件,建议将2个文件放在服务器
// 只需要手动引入这一个文件即可,另一个文件在该文件中引用了
<script src="<%= BASE_URL %>js/pdf.js"></script>
// 在线地址
<script src="https://static.wangcp.top/js/pdf.js"></script>
组件代码
<template>
<div>
<div v-for="page in totalPages" :key="page">
<canvas :ref="`pdfCanvas${page}`" :id="'pdfCanvas-' + page"></canvas>
</div>
</div>
</template>
<script>
export default {
data() {
return {
pdfInstance: null,
totalPages: 0
};
},
props:{
url:{
type:String,
default:""
}
},
methods: {
async initRender () {
await this.loadPdf();
},
async loadPdf() {
// 1.获取在线链接的 buffer 流
const pdfData = await this.fetchPdfData(this.url);
// 2.渲染pdf
await this.renderPdf(pdfData);
},
async fetchPdfData(url) {
const response = await fetch(url);
return response.arrayBuffer();
},
async renderPdf(pdfData) {
const pdfjsLib = window['pdfjs-dist/build/pdf'];
this.pdfInstance = await pdfjsLib.getDocument({data: pdfData}).promise;
// 获取总页数
this.totalPages = this.pdfInstance.numPages;
// 循环渲染
this.$nextTick(async () => {
for (let pageNumber = 1; pageNumber <= this.totalPages; pageNumber++) {
await this.renderPage(pageNumber);
}
})
},
async renderPage(pageNumber) {
// 单页渲染,获取 canvas 元素, 获取页面数据,宽高,渲染,
const pdfCanvas = this.$refs['pdfCanvas' + pageNumber][0];
const page = await this.pdfInstance.getPage(pageNumber);
const viewport = page.getViewport({scale: 1});
const canvasContext = pdfCanvas.getContext('2d');
pdfCanvas.width = viewport.width;
pdfCanvas.height = viewport.height;
const renderContext = {
canvasContext,
viewport
};
await page.render(renderContext).promise;
}
}
};
</script>
组件使用
<pdf ref='pdfRef' url='xxx.pdf'/>
import pdf from 'pdf.vue'
pdfRef.initRender()