利用vant的组件Uploader实现文件上传,并且实现上传的文件在前端进行预览,不涉及服务端。实现的效果:pdf文档如果多页,可进行上下滑动。在移动端正常使用,pc端暂无验证。
参考了这个https://github.com/Hanpeng-Chen/hampton-demo-repo,里面有好几种方法,我使用的只是其中一种。
1、安装插件
npm install pdfjs-dist@^2.0.943
2、引入插件
注:第二行很重要,不用会报错
import pdfJS from 'pdfjs-dist';
pdfJS.GlobalWorkerOptions.workerSrc = require('pdfjs-dist/build/pdf.worker.entry');
3、html部分
<template>
<div class="hp-container">
<div class="scroll-pdf-contanier" id="scrollPdfBox">
<div v-for="index in pdfTotalPages" :key="index">
<canvas :ref="`scrollPdfCanvas${index}`" class="content"></canvas>
</div>
</div>
<van-uploader accept="file" result-type="text" v-model="fileList" multiple :max-count="1" class="uploader" ref="file" :after-read="afterRead" :before-read="beforeRead"></van-uploader>
<van-row type="flex" justify="space-between" align="center">
<van-col>
<van-button @click="back">返回</van-button>
</van-col>
<van-col>
<van-button type="info" @click="upload">上传文件</van-button>
</van-col>
</van-row>
</div>
</template>
4、js部分
import pdfJS from 'pdfjs-dist';
pdfJS.GlobalWorkerOptions.workerSrc = require('pdfjs-dist/build/pdf.worker.entry');
export default {
name: 'uploadFile',
components: {
},
data () {
return {
fileList: [],
pdfTotalPages: 1,
pdfData: null, // PDF的base64
scale: 1 // 缩放值
};
},
methods: {
back () {
this.$router.go(-1);
},
upload () {
this.$refs.file.chooseFile();
},
// 文件读取前的回调函数,返回 false 可终止文件读取,支持返回 Promise
beforeRead (file) {
if (Array.isArray(file) && file.length > 1) {
this.$toast('只能上传一份文件');
return false;
}
if (file.type !== 'application/pdf') {
this.$toast('请上传 pdf 格式的文件');
return false;
}
return true;
},
// 文件读取完成后的回调函数
afterRead (file) {
const _this = this;
var reader = new FileReader();
reader.readAsDataURL(file.file); // 读取文件
reader.onload = function (e) {
const data = atob(reader.result.substring(reader.result.indexOf(',') + 1));
_this.loadPdfData(data);
}
reader.onerror = () => {
_this.$toast('文件解析失败,请重新上传');
_this.fileList = [];
_this.$refs.file.deleteFile();
};
},
loadPdfData (data) {
// 读取base64的pdf流文件
this.pdfData = pdfJS.getDocument({
data: data, // PDF base64编码
cMapUrl: '',
cMapPacked: true
});
this.renderScrollPdf();
},
renderScrollPdf () {
this.pdfData.promise.then(pdf => {
this.pdfTotalPages = pdf.numPages;
this.renderScrollPdfPage(1);
});
},
// 渲染连续滚动PDF
renderScrollPdfPage (num) {
this.pdfData.promise.then(pdf => {
const numPages = pdf.numPages;
pdf.getPage(num).then(page => {
const canvas = this.$refs[`scrollPdfCanvas${num}`][0];
// 为了预览的文件内容比较清晰,所以缩放值使用了3
const viewport = page.getViewport(3);
console.log('viewport :>> ', viewport);
canvas.height = viewport.height * this.scale;
canvas.width = viewport.width * this.scale;
const ctx = canvas.getContext('2d');
const renderContext = {
canvasContext: ctx,
viewport: viewport
};
page.render(renderContext).then(() => {
if (num < numPages) {
this.renderScrollPdfPage(num + 1);
}
});
});
});
}
}
};
5、style部分
// 隐藏文件上传样式
::v-deep .van-uploader {
display: none;
}
// 防止预览文件超过一屏
.content{
width: 750px;
}
版权归原作者 Min*Yan 所有, 如有侵权,请联系我们删除。