使用 fetch 获取pdf 的buffer 流,然后使用 pdfjs 获取每一页的数据,从而绘制在 canvas 上
文件列表
- pdf.js
- pdf.worker.js
在 index.html 上引入pdd.js,可以使用 cdn 链接,也可以使用本地文件,建议将2个文件放在服务器
// 只需要手动引入这一个文件即可,另一个文件在该文件中引用了
<script src="<%= BASE_URL %>js/pdf.js"></script>
组件代码
<template>
<div style="width: 100%;height: 100%;overflow: auto;" id="pdfviewRef">
<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 () {
document.querySelector('#pdfviewRef').innerHTML = ''
await this.loadPdf();
},
async loadPdf() {
const pdfData = await this.fetchPdfData(this.url);
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, cMapUrl: 'https://cdn.jsdelivr.net/npm/pdfjs-dist@3.10.111/cmaps/', cMapPacked: true}).promise;
this.totalPages = this.pdfInstance.numPages;
this.$nextTick(async () => {
for (let pageNumber = 1; pageNumber <= this.totalPages; pageNumber++) {
await this.renderPage(pageNumber);
}
})
},
async renderPage(pageNumber) {
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()