在工作中可能会遇到前端展示pdf文件进行预览并提供下载的需求场景,例如操作指引,这个时候需要寻找一款实现该功能的插件,以pdjjs举例子
1. 安装pdf.js
npm install pdfjs-dist
2. 引入pdf.js
import pdfjsLib from 'pdfjs-dist'
3.加载pdf文件流
这个地方区分是请求后端接口还是直接加载本地pdf文件
如果是请求后端获取到的pdf文件流
axios.get('/api/pdfdoc', { responseType: 'blob' })
.then(response => {
const blob = new Blob([response.data], { type: 'application/pdf' })
this.viewPdf(blob)
})
如果是读取本地的文件,则url地址直接是本地的地址
在viewPdf()方法中,使用getDocument()方法加载pdf文件:
viewPdf(fileUrl){
let _this = this;
PDFJS.getDocument(fileUrl).then(fileContent =>{
_this.pdfDoc = fileContent;
setTimeout(()=>{
_this.renderPage();
},100)
})
},
4. 渲染pdf
使用pdf.js的Renderer渲染pdf文件。可以使用getViewport()方法获取pdf页面的视图大小。
在renderPdf()方法中,遍历pdf文件的每个页面,并使用Renderer将其渲染:
renderPage(){
// 获取页面canvas节点
let canvas = document.getElementById('infoPrvacy-content');
const ctx = canvas.getContext("2d");
this.pdfDoc.getPage(1).then(page =>{
// 文件页面的视图 1倍
const viewport = page.getViewport(0.5);
// 将画布宽度设置为视图宽度
canvas.width = viewport.width;
canvas.height = viewport.height;
const renderContext = {
canvasContext: ctx,
viewport: viewport
};
console.log(renderContext);
// 渲染页面内容:参数是canvas画布上下文,以及文件视图
page.render(renderContext);
})
},
注意: 一定要引用字体包,否则会乱码
const obj = {};
obj.cMapUrl = '/assets/pdfjs/cmaps/';
obj.cMapPacked = true;
obj.url = './static/test.pdf'
this.viewPdf(obj)
js部分的代码
<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>