利用vant的组件Uploader实现文件上传,并且实现上传的文件在前端进行预览,不涉及服务端。实现的效果:pdf文档如果多页,可进行上下滑动。在移动端正常使用,pc端暂无验证。
参考了这个https://github.com/Hanpeng-Chen/hampton-demo-repo,里面有好几种方法,我使用的只是其中一种。
目录
1、安装插件
2、引入插件
3、html部分
4、js部分
5、style部分
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;}