在移动端直接预览上传的文件,一开始考虑成型的线上文件预览服务如xdoc,但是考虑到纯线上服务我们设计报销审批的敏感文件信息,自己部署服务需要付费,所以另辟蹊径,单独对各个文件类型进行预览处理
参考问答: segmentfault.com/q/101000002…
一、图片预览
第一种方式
参考了blog.csdn.net/qq_39258914… 并使用了文件中提及的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>
点击可关闭预览(移动端够用了,图片预览比较简单哈哈,可以用其他插件实现也)
第二种
转成base64链接
`data:image/jpg;base64,` + btoa(new Uint8Array(res).reduce((data,key) => {data + String.fromCharCode(key),''}))
二、pdf预览
pdf预览使用vue-pdf插件
github地址:github.com/FranckFreib…
参考其中的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地址:github.com/SheetJS/she…,,我们用到的在这里
照葫芦画瓢,预览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的课表,信息也比较多,有余力的自己调整一下)
注:
XLSX可以使用sheet_to_json进行转换,HTML可以使用v-html放在dom结构上
var work = XLSX.read(response, {type: 'binary'})
console.log(111==="",work)
// let sheet = work.SheetNames[0]
let sheet = work.SheetNames
console.log(sheet)
try {
// 获取当前工作表的数据
let htmlData
for (var i = 0; i < sheet.length; i++) {
const workSheet = work.Sheets[sheet[i]]
console.log(workSheet,'workSheet')
if (i == 0) {
htmlData = `<div>${sheet[i]}</div>`
} else {
htmlData += `<div>${sheet[i]}</div>`
}
htmlData += XLSX.utils.sheet_to_html(workSheet,{header:'',footer:''})
// console.log(htmlData)
}
// // 转换为数据 1.json数据有些问题 2.html样式需要修改
// const sheet2JSONOpts = { defval: '' }
// let jsonData = XLSX.utils.sheet_to_json(workSheet,sheet2JSONOpts)
htmlData = htmlData === '' ? htmlData : htmlData.replace(/<table/g, `<table class="tableFormApprove" border="1px solid #ccc" cellpadding="0" cellspacing="0"`)
htmlData = htmlData === '' ? htmlData : htmlData.replace(/<tr/g,`<tr style="background:#F5F7FA"`)
this.sheetActive = htmlData
} catch (error) {
this.sheetActive = `<h1 style='text-align: center;'>无内容</h1>`
}
四、word预览
word预览使用mammoth.js进行转换和显示
github地址:github.com/mwilliamson… 可以参考学习!画个重点,我用的是这部分
如是先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");
}
}
我将这几个组件的应用封装在了图片预览组件当中,用模态窗口做了承接,做了简单的文件类型的判断,根据不同的业务需求也可以在应用时做不同的处理