1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > vue移动端文件预览

vue移动端文件预览

时间:2019-11-10 19:09:36

相关推荐

vue移动端文件预览

vue移动端文件预览

前言:整体思路:具体实现:一、外壳(vViews.vue):二、文件预览:1.图片预览:2.pdf文件预览:3.docx文件预览:4.excel表格预览(xls、xlsx格式表格):5.txt文件预览:三、补充外壳文件css样式:四、js文件补充:

前言:

最近遇到一个移动端需求,要求在移动端预览上传的附件,在网上找了很多资料,最后参考CSDN博主「蛋蛋fighting哈湫」的原创文章实现了功能,并结合自己的项目情况,整理了这份文档。

原文链接:/u012439689/article/details/106570080/

整体思路:

实现在不下载的情况下预览附件内容功能;使用不同组件分别实现不同文件类型预览功能。目前实现功能:图片、pdf文件、docx、excel表格(xls、xlsx格式表格)、txt文件预览;样式使用less;

具体实现:

一、外壳(vViews.vue):

将各个组件进行整合,在页面中引用时更加方便,项目使用了vant组件库,在之前的文章中描述了如何安装,这里不做赘述。

<template><div class="viewBox" v-if="isShow"><!-- 关闭按钮 --><van-icon class="closeBtn" name="cross" @click="isShow = false" /></div></template>

export default {props: {datas: {},type: {}},data() {return {isShow: false};},methods: {/*** 处理展示数据*/showFile(newVal) {}}};

<style lang="less" scoped>.viewBox {width: 100vw;height: 100vh;overflow: hidden;background: #ffffff;position: absolute;top: 0;left: 0;z-index: 2000;.closeBtn {position: absolute;top: 10px;right: 10px;z-index: 10;font-size: 24px;}}</style>

在父组件中引用:

<template><div><!-- 附件列表 --><div v-for="(item, index) in fileList":key="index"@click="showFile(item)">{{item.file_name}}</div><v-views ref="vViews" :datas="src" :type="type"></v-views></div></template>

import vViews from '@/components/vViews';export default {components: {vViews },data() {return {fileList: [], // 附件列表src: '', // 传参type: '', // 附件类型fileObj: {} // 存放已获取的数据流};},methods: {/*** 点击查看附件*/showFile(item) {// 获取允许预览文件类型const typeObj = {'.docx': 'word','.pdf': 'pdf','.jpg': 'img','.png': 'img','.xls': 'excel','.xlsx': 'excel','.txt': 'txt',};this.type = typeObj[item.file_type] || '';// 已经调用过接口获取到了文件流数据if (this.fileObj[item.file_name]) {this.openFile(this.fileObj[item.file_name]);} else {this.downloadFile(item);}},/*** 打开文件预览组件*/openFile(datas) {this.src = datas.fileBinary;this.$nextTick(()=> {this.$refs.vViews.isShow = true;this.$refs.vViews.showFile(this.src);});},/*** 下载接口*/downloadFile(item) {// 判断是否允许预览if (this.type !== '') {const res = {...}; // 这里指从后台接口获取的数据 this.fileObj[res.data.fileName] = res.data;this.openFile(res.data);} else {const types = item.file_type.substr(1);this.$toast(`${types}文件类型暂不支持预览`);}},}};

二、文件预览:

1.图片预览:

因为我的项目安装了vant,所以这里使用了vant的ImagePreview图片预览组件,在外壳(vViews.vue)页面里进行导入使用。

import {ImagePreview } from 'vant';export default {methods: {showFile(newVal) {if (this.type === 'img') {// 图片预览,这里是后台返回了base64的数据,处理成了blob格式const val = this.$base64ToBlob(newVal, 'image/jpeg');this.newSrc = window.URL.createObjectURL(val);// vant自带图片预览组件const that = this;ImagePreview({images: [this.newSrc],showIndex: false,onClose() {that.isShow = false;},});}}}};

2.pdf文件预览:

预览pdf文件,并实现展示当前、总页数及前后翻页功能。

安装vue-pdf依赖

npm install --save vue-pdf

<template><div class="viewBox" v-if="isShow"><!-- 关闭按钮 --><van-icon class="closeBtn" name="cross" @click="isShow = false" /><!-- pdf组件 --><div class="pdf-box" v-if="type === 'pdf'"><div class="pdf_btn" v-if="pageTotalNum > 1"><van-button plaincolor="#07AC7F"@click="prePage">上一页</van-button>{{pageNum}}/{{pageTotalNum}}<van-button plaincolor="#07AC7F"@click="nextPage">下一页</van-button></div><pdf:page="pageNum":src="newSrc"@progress="loadedRatio = $event"@num-pages="pageTotalNum=$event" ></pdf></div></div></template>

import pdf from 'vue-pdf'; // pdfexport default {components: {pdf },data() {return {pageNum: 1,pageTotalNum: 1, // 总页数newSrc: '', // 路径};},methods: {showFile(newVal) {if (this.type === 'pdf') {this.pageNum = 1;this.pageTotalNum = 1;// pdf预览const val = this.$base64ToBlob(newVal, 'application/pdf');const href = window.URL.createObjectURL(val);this.newSrc = pdf.createLoadingTask(href);}},/*** 上一页*/prePage() {let page = this.pageNum;page = page > 1 ? page - 1 : this.pageTotalNumthis.pageNum = page;},/*** 下一页*/nextPage() {let page = this.pageNum;page = page < this.pageTotalNum ? page + 1 : 1this.pageNum = page;},}};

3.docx文件预览:

安装mammoth依赖

npm install --save mammoth

<template><div class="viewBox" v-if="isShow"><!-- 关闭按钮 --><van-icon class="closeBtn" name="cross" @click="isShow = false" /><!-- docx组件 --><div class="word-box" v-if="type === 'word'" ref="docPreview"></div></div></template>

import mammoth from 'mammoth'; // word文档export default {methods: {showFile(newVal) {if (this.type === 'word') {// word文档预览,只能预览docxconst val = this.$base64ToBlob(newVal, 'application/msword');mammoth.convertToHtml({arrayBuffer: val }).then(this.displayResult).done();}},/*** word----docx预览*/displayResult(result) {this.$refs.docPreview.innerHTML = result.value || '';},}};

4.excel表格预览(xls、xlsx格式表格):

实现表格预览,实现多表格切换显示。

安装xlsx依赖

npm install xlsx --save

<template><div class="viewBox" v-if="isShow"><!-- 关闭按钮 --><van-icon class="closeBtn" name="cross" @click="isShow = false" /><!-- 表格组件 --><div class="table-box" v-if="type === 'excel'"><van-tabs class="table-tab"v-if="sheetNames.length"title-active-color="#07AC7F"color="#07AC7F"@click="clickTab"><van-tabv-for="(item, index) in sheetNames" :key="index":name="item":title="item"></van-tab></van-tabs><div class="tableBox" ref="excPreview"></div></div></div></template>

import XLSX from 'xlsx'; // excel表格export default {methods: {data() {return {sheetNames: [],wsObj: {}};},showFile(newVal) {if (this.type === 'excel') {// excel预览this.sheetNames = []; // 重置const wb = XLSX.read(newVal, {type: 'base64' });this.sheetNames = [...wb.SheetNames]; // 数组this.wsObj = {...wb.Sheets };this.changeExcel(this.sheetNames[0]);}},/*** 切换表格*/clickTab(name) {this.changeExcel(name);},/*** 处理excel表格*/changeExcel(item) {// 获取当前选中表格对象const ws = this.wsObj[item];const keyArr = Object.keys(ws) || [];const HTML = keyArr.length > 1 ? XLSX.utils.sheet_to_html(ws): '<html><head><meta charset="utf-8"/>' +'<title>SheetJS Table Export</title></head><body><div class="myTable">暂无数据</div></body>' +'</html>';this.$nextTick(()=> {this.$refs.excPreview.innerHTML = HTML;// 获取表格dom元素const tables = this.$refs.excPreview.children[2];// 添加完毕后 通过空格将数组组装为字符串tables.className = 'myTable';})},}};

5.txt文件预览:

<template><div class="viewBox" v-if="isShow"><!-- 关闭按钮 --><van-icon class="closeBtn" name="cross" @click="isShow = false" /><div class="txt-box" v-if="type === 'txt'" ref="txtPreview"></div></div></template>

export default {methods: {showFile(newVal) {if (this.type === 'txt') {// txtconst val = this.$base64ToBlob(newVal, 'text/plain');const reader = new FileReader();const that = this;reader.readAsText(val);reader.onload = function () {that.$refs.txtPreview.innerHTML = reader.result || '';}}}}};

三、补充外壳文件css样式:

<style lang="less" scoped>.pdf-box, .word-box, .table-box, .txt-box {width: 100vw;height: 100vh;}.pdf-box {.pdf_btn {padding: 0 10px;height: 44px;box-sizing: border-box;display: flex;justify-content: center;align-items: center;/deep/.van-button {margin: 0 2px;height: 24px;&:nth-child(1) {border-radius: 15px 0 0 15px;}&:nth-child(2) {border-radius: 0 15px 15px 0;}}}>span {width: 100%;height: calc(100% - 44px);}}.word-box {padding: 40px 15px 15px;box-sizing: border-box;overflow: auto;}.table-tab {width: calc(100% - 44px);}// 考核模块table样式.tableBox {width: 100vw;height: calc(100vh - 44px);overflow: auto;// 表格边框@table-border: 1px solid #929292;// 表格/deep/ table.myTable {width: auto;height: auto;color: #333333;// 合并边框border-collapse: collapse;border: @table-border;// th,tdth, td {// 禁止换行white-space: nowrap;overflow: hidden;text-overflow: ellipsis;background: #ffffff;padding: 10px;border: @table-border;}th {// 正常粗细font-weight: normal;// 表头信息居左显示&.th-info {text-align: left;span {// 表头信息样式优化margin-right: 30px;}}}// 表格内容居中td {text-align: center;}}/deep/ div.myTable {text-align: center;margin: 30% auto;}}.txt-box {padding: 40px 15px 15px;box-sizing: border-box;overflow: auto;}</style>

四、js文件补充:

function base64ToBlob(base64, mimetype, slicesize) {let num = 0;if (!window.atob || !window.Uint8Array) {return null;}mimetype = mimetype || '';slicesize = slicesize || 512;const bytechars = atob(base64);const bytearrays = [];for (let a = 0; a < bytechars.length; a += slicesize) {const slice = bytechars.slice(a, a + slicesize);const bytenums = new Array(slice.length);for (var i = 0; i < slice.length; i++) {bytenums[i] = slice.charCodeAt(i);}const bytearray = new Uint8Array(bytenums);bytearrays[bytearrays.length] = bytearray;}return new Blob(bytearrays, {type: mimetype});}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。