最近接到了来自产品的一个需求,将我们的erp的移动端中的审批部分的上传附件进行优化,可以在移动端直接预览上传的文件(一般为发票和凭据图片文档等),所以需要由前端直接对文件进行预览(之前的方式是后端返回网络链接,下载下来之后在本地自行进行文件预览)最后商榷的是最大类型的预览文件(支持pdf,各类图片,word和excel文件)
一开始考虑成型的线上文件预览服务如xdoc,但是考虑到纯线上服务我们设计报销审批的敏感文件信息,自己部署服务需要付费啊哈哈(你们懂得),所以另辟蹊径,单独对各个文件类型进行预览处理
参考问答:
https://segmentfault.com/q/1010000020978257
https://segmentfault.com/q/1010000022074502/
一、图片预览
参考了vue移动端图片预览组件_qq_39258914的博客-CSDN博客 并使用了文件中提及的w-previewimg图片预览组件(暂时采用这个预览单个图片)
安装
npm install -s w-previewimg
引入
import wimg from "w-previewimg"; //图片预览插件
使用,current即当前需要看的图片
<wimg
:show="showBigImg"
:imgs="thumbsList"
:currentImg="current"
@close="showBigImg=false"
class="wimg"
></wimg>
效果如下,点击可关闭预览(移动端够用了,图片预览比较简单哈哈,可以用其他插件实现也)
二、pdf预览
pdf预览使用vue-pdf插件
github地址:https://github.com/FranckFreiburger/vue-pdf
参考其中的demo实现,组件代码如下,可以在用到的地方按需引用,我在最后的图片预览组件中会提供,我们涉及的预览比较简单(单页pdf预览)有需要的可以自己看一下github中的demo做深层次的实现
<template>
<div class="excel-container">
<pdf ref="pdf" :src="url"></pdf>
</div>
</template>
<style sceped lang="scss">
.excel-container {
width: 100%;
}
</style>
<script>
import pdf from "vue-pdf"; //pdf预览插件
export default {
name: "pdfPreview",
props: {
url: {
type: String,
required: true
}
},
components: { pdf },
data() {
return {
data: []
};
},
watch: {
url(val) {
console.log(val, "val");
this.previewFile();
}
},
methods: {
previewFile() {
var self = this;
try {
this.pdfUrl = this.url;
let loadingTask = pdf.createLoadingTask(url);
} catch (e) {
console.log(e);
this.$vux.loading.hide();
this.$emit("errorPreview");
}
}
}
};
</script>
三、excel文件预览
感谢前面中问答给出的提示,在本vue项目中采用了sheet.js插件进行excel转为html然后在页面上渲染出来(美观度一般,我调试的不到位)
github地址:https://github.com/SheetJS/sheetjs,,我们用到的在这里
照葫芦画瓢,预览excel组件源码如下
<template>
<div class="excel-container">
<div ref="preview"></div>
</div>
</template>
<style sceped lang="scss">
.excel-container {
width: 100%;
}
</style>
<script>
import XLSX from "xlsx";
export default {
name: "excelPreview",
props: {
url: {
type: String,
required: true
}
},
data() {
return {
data: []
};
},
watch: {
url(val) {
console.log(val, "val");
this.previewFile();
}
},
methods: {
previewFile() {
var self = this;
try {
var req = new XMLHttpRequest();
req.open("GET", this.url, true);
req.responseType = "arraybuffer";
req.onload = e => {
console.log(req.response, "req.response");
var binary = "";
var bytes = new Uint8Array(req.response);
var length = bytes.byteLength;
for (var i = 0; i < length; i++) {
binary += String.fromCharCode(bytes[i]);
}
var wb = XLSX.read(binary, { type: "binary" });
var wsname = wb.SheetNames[0];
var ws = wb.Sheets[wsname];
var HTML = XLSX.utils.sheet_to_html(ws);
if (this.$refs.preview) {
this.$refs.preview.innerHTML = HTML;
}
};
req.send();
} catch (e) {
console.log(e);
this.$emit("errorPreview");
}
}
}
};
</script>
预览效果(我这个有点丑,功能实现了哈,我上传的FocusT25的课表,信息也比较多,有余力的自己调整一下)
四、word预览
word预览使用mammoth.js进行转换和显示
github地址:https://github.com/mwilliamson/mammoth.js 可以参考学习!画个重点,我用的是这部分
然后差别在于,我的文档链接都是网络链接,预览网络链接的word文档需要先下载下来,然后按例子进行转换,参考了一下api,这个方法可以传path也可以传buffer
如是先get请求获取文件buffer然后再进行转换
关键部分代码
previewFile() {
let _this=this;
try {
var xhr = new XMLHttpRequest();
xhr.open("GET", this.url);
xhr.responseType = "arraybuffer";
let self = this;
xhr.onload = function(e) {
var arrayBuffer = xhr.response; //arrayBuffer
mammoth
.convertToHtml({ arrayBuffer: arrayBuffer })
.then(displayResult)
.done();
function displayResult(result) {
console.log(result);
self.$refs.docPreview.innerHTML = result.value || "";
}
};
xhr.send();
} catch (e) {
console.log(e);
_this.$emit("errorPreview");
}
}
这个转换出来还是挺好看的哈哈
我将这几个组件的应用封装在了图片预览组件当中,用模态窗口做了承接,做了简单的文件类型的判断,根据不同的业务需求也可以在应用时做不同的处理
特此记录,欢迎批评指正