背景:iframe展示 pdf 在 IE 浏览器直接下载文件,无法预览展示。
1.安装 pdfjs-dist,别的版本有遇到些未知错误,最后用的 2.0.943 版本
npm install pdfjs-dist@2.0.943 --save
2.创建组件文件
没做翻页,展示全部页下滑展示
<template>
<div class="pdf-wrap">
<div class="canvas-container"></div>
</div>
</template>
<script>
const pdfJS = require('pdfjs-dist')
pdfJS.GlobalWorkerOptions.workerSrc = require('pdfjs-dist/build/pdf.worker.entry')
export default {
props: {
// pdf 的url地址
src: String
},
mounted() {
this.loadPdfData()
},
data() {
return {
pageNo: null,
pdfPageNumber: null,
pdfTotalPages: 1,
renderingPage: false,
pdfData: null, // PDF的base64
scale: 1.5, // 缩放值
}
},
methods: {
loadPdfData() {
this.pdfData = pdfJS.getDocument(this.src)
// console.log(this.pdfData)
this.renderPage()
},
// 渲染PDF
renderPage() {
this.renderingPage = true
const canvasContainer = document.querySelector('.canvas-container')
canvasContainer.innerHTML = '';
this.pdfData.promise.then((pdf) => {
this.pdfPageNumber = pdf.numPages
for(let i = 1; i <= pdf.numPages; i++) {
pdf.getPage(i).then((page) => {
// 获取DOM中为预览PDF准备好的canvasDOM对象
// let canvas = this.$refs.myCanvas
let canvas = document.createElement('canvas')
canvas.className = 'pdf-container'
let viewport = page.getViewport(this.scale)
canvas.height = viewport.height
canvas.width = viewport.width
canvasContainer.appendChild(canvas)
let ctx = canvas.getContext('2d')
let renderContext = { canvasContext: ctx, viewport: viewport }
page.render(renderContext).then(() => {
this.renderingPage = false
})
})
}
})
}
},
}
</script>
<style scoped>
.pdf-wrap {
display: flex;
flex-direction: column;
align-items: center;
}
.canvas-container {
border: 1px dashed #e1e1e1;
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
}
canvas {
border: 1px dashed black;
margin-bottom: 10px;
width: 100%;
height: 100%;
}
</style>
然后在对应的地方引入即可,传入对应的 src 路径;
3.做了分页的代码
<template>
<div class="pdf-wrap">
<div class="canvas-container">
<canvas ref="myCanvas" class="pdf-container"> </canvas>
</div>
<div class="pagination-wrapper mt10">
<el-button type="text" @click="clickPre">上一页</el-button
><span class="ml8 mr8">第{{ pageNo }} / {{ pdfPageNumber }}页</span
><el-button type="text" @click="clickNext">下一页</el-button>
<!-- <el-pagination
background
layout="next , pager, prev"
@current-change="handleCurrentChange"
:page-size="1"
:total="pdfTotalPages">
</el-pagination> -->
</div>
</div>
</template>
<script>
const pdfJS = require('pdfjs-dist')
pdfJS.GlobalWorkerOptions.workerSrc = require('pdfjs-dist/build/pdf.worker.entry')
export default {
props: {
src: String
},
mounted() {
this.loadPdfData()
},
data() {
return {
pageNo: null,
pdfPageNumber: null,
pdfTotalPages: 1,
renderingPage: false,
pdfData: null, // PDF的base64
scale: 1.5, // 缩放值
}
},
methods: {
// 加载pdf数据
loadPdfData() {
this.pdfData = pdfJS.getDocument(this.src)
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
})
},
},
}
</script>
<style scoped>
.pdf-wrap {
display: flex;
flex-direction: column;
align-items: center;
}
.canvas-container {
/* width: 600px; */
/* height: 500px; */
border: 1px dashed #e1e1e1;
position: relative;
display: flex;
justify-content: center;
}
.scroll-pdf-contanier {
width: 600px;
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>
补充:
如果要展示盖章文件,会有印章不展示的问题,解决方案如下:
在node_modules里找到 pdfjs-dist 文件下的 pdf.worker.js 搜索 data.fieldType 注释掉 _this2.setFlags(_util.AnnotationFlag.HIDDEN) 就可以了。
本地注释后生产怎么处理,网上处理办法挺多的,都可以借鉴下:
我采用的处理办法:新建一个initInstall.js文件和package.json同级,执行下node initInstall.js 替换下对应文件的内容,然后再运行项目
const fs = require('fs');
const filePath = 'node_modules/pdfjs-dist/build/pdf.worker.js';
fs.readFile(filePath, 'utf8', (err, data) => {
if (err) {
console.error(err);
return;
}
const modifiedData = data.replace(
/_this2.setFlags/g,
'// _this2.setFlags'
)
fs.writeFile(filePath, modifiedData, 'utf8', (err) => {
if (err) {
console.error(err);
return;
}
console.log('File modified successfully!');
});
});