pdfjs-dist 实现pdf文件在线预览
项目要求实现pdf文件在线预览,并且pdf预览通过上下页滚动pdf,且兼容ie浏览器
浏览器兼容参照了 这位博主的文章,选择用pdfjs-dist 实现
实现效果
这是我随便写的一个pdf(一共2页),可通过点击上下换页
谷歌浏览器
ie11
实现过程
(1)安装pdfjs-dist
npm install --save pdfjs-dist@2.0.943
这里需要指定2.0.943的版本,试过其他版本的都会多多少少在引入,执行行数时报错
(2)代码部分
<template>
<div class="main-container">
<input type="file" ref="fielinput" @change="uploadFile" />
<div class="canvas-container">
<canvas ref="myCanvas" class="pdf-container"> </canvas>
</div>
<div class="pagination-wrapper">
<button @click="clickPre">上一页</button>
<span>第{{ pageNo }} / {{ pdfPageNumber }}页</span>
<button @click="clickNext">下一页</button>
</div>
</div>
</template>
<script>
const pdfJS = require("pdfjs-dist");
pdfJS.GlobalWorkerOptions.workerSrc = require("pdfjs-dist/build/pdf.worker.entry");
export default {
mounted() {},
data() {
return {
pageNo: null,
pdfPageNumber: null,
pdfTotalPages: 1,
renderingPage: false,
pdfData: null, // PDF的base64
scale: 1, // 缩放值
};
},
methods: {
uploadFile() {
let inputDom = this.$refs.fielinput;
let file = inputDom.files[0];
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
let data = atob(
reader.result.substring(reader.result.indexOf(",") + 1)
);
this.loadPdfData(data);
};
},
loadPdfData(data) {
// 引入pdf.js的字体
let CMAP_URL = "https://unpkg.com/pdfjs-dist@2.0.943/cmaps/";
//读取base64的pdf流文件
this.pdfData = pdfJS.getDocument({
data: data, // PDF base64编码
cMapUrl: CMAP_URL,
cMapPacked: true,
});
console.log(this.pdfData);
this.renderPage(1);
this.renderScrollPdf();
},
// 根据页码渲染相应的PDF
renderPage(num) {
this.renderingPage = true;
this.pdfData.promise.then((pdf) => {
this.pdfPageNumber = pdf.numPages;
pdf.getPage(num).then((page) => {
// 获取DOM中为预览PDF准备好的canvasDOM对象
let canvas = this.$refs.myCanvas;
let viewport = page.getViewport(this.scale);
canvas.height = viewport.height;
canvas.width = viewport.width;
let ctx = canvas.getContext("2d");
let renderContext = {
canvasContext: ctx,
viewport: viewport,
};
page.render(renderContext).then(() => {
this.renderingPage = false;
this.pageNo = num;
});
});
});
},
clickPre() {
if (!this.renderingPage && this.pageNo && this.pageNo > 1) {
this.renderPage(this.pageNo - 1);
}
},
clickNext() {
if (
!this.renderingPage &&
this.pdfPageNumber &&
this.pageNo &&
this.pageNo < this.pdfPageNumber
) {
this.renderPage(this.pageNo + 1);
}
},
renderScrollPdf() {
this.pdfData.promise.then((pdf) => {
this.pdfTotalPages = pdf.numPages;
this.renderScrollPdfPage(1);
});
},
},
};
</script>
<style scoped>
.main-container {
display: flex;
flex-direction: column;
align-items: center;
}
.canvas-container {
width: 400px;
height: 500px;
border: 1px dashed black;
position: relative;
display: flex;
justify-content: center;
}
.scroll-pdf-contanier {
width: 400px;
height: 500px;
border: 1px dashed black;
position: relative;
display: flex;
flex-direction: column;
overflow-y: scroll;
}
.pdf-container {
width: 100%;
height: 100%;
}
.scroll-pdf-container {
width: 350px;
}
.pagination-wrapper {
display: flex;
justify-content: center;
align-items: center;
}
</style>
(3)原理
首先是要传递给pdfjs-dist展示的是以base64的方式传递,这里用了上传文件,将文件流转化成base64进行模拟,一般是由后台传给前端base64数据直接渲染
uploadFile() {
let inputDom = this.$refs.fielinput;
let file = inputDom.files[0];
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
let data = atob(
reader.result.substring(reader.result.indexOf(",") + 1)
);
this.loadPdfData(data);
};
},
loadPdfData函数接受到base64数据后,调用pdf-dist的方法将pdf转换成canvas,相当于用图片的方式展示pdf,而各个浏览器都支持图片,那么就少了很多兼容的问题了
再配合pdf的页数,点击按钮上下切换,功能基本实现