前言
我详细这个当这个需求来的时候,有很大一部分人跟我的想法是一样的纯前端如何去实现多文件预览。确实这个功能很让人头疼,虽然市面上也有很多成型的插件,但是极少数能满足不同文件的预览,要么就是用第三方的链接去预览。这种虽然是最简单的方式。但是好多公司不会同意,涉及到以后后期是否有变动的问题。以及文件泄露的问题。那么下面我就给大家介绍一下我这边是如何处理这功能的。
实现效果图
html部分我这边是将docx和excel用弹框的形式去展示
<el-dialog
:title="titles"
:visible.sync="dialogVisible"
width="60%"
class="filebox"
@close="closeDialog"
>
<div ref="childRef" class="childRef" v-if="wordShow"></div>
<div id="luckysheet" ref="luckysheet" style="height: 600px" v-if="excelShow"></div>
</el-dialog>
data中的参数定义
data(){
return{
fileUrl: "",
dialogVisible: false,
titles: "",
excelShow: false,
wordShow: false,
}
}
先来处理最简单的就是pdf的预览代码如下
//大多数都是采用iframe去做pdf的文件处理的
PreviewFile(e){//点击预览事件的时候拿到当前对应的一个文件属性
if (e.fileType == "pdf") {//判断文件类型
const newWindow = window.open();
newWindow.document.write(
'<iframe width="100%" height="100%" src="' +
文件地址 +
'" frameborder="0" allowfullscreen></iframe>'
);
}
}
其次就是word的文件预览稍微难一点代码如下
//word 需要装一个插件
npm i docx-preview -S
// 然后引入
import { renderAsync } from "docx-preview";
if (e.fileType == "docx") {//判断文件类型
this.dialogVisible = true;
this.excelShow = false;
this.wordShow = true;
this.titles = e.fileName + "文件预览";
this.$nextTick(() => {
fetch(完整的文件地址)
.then((response) => {
let docData = response.blob(); //将文件转换成bolb形式
//选择要渲染的元素
let childRef = document.getElementsByClassName("childRef");
//用docx-preview渲染
renderAsync(docData, childRef[0]).then((res) => {});
})
.catch((error) => {
console.log(error);
});
});
}
最后就是xlsx的文件预览个人认为最复杂一个
//xlsx也需要装一个插件
npm install luckyexcel
需要在utils下建一个excel.js文件
export function asynLoad(src, isCss = false) {
return new Promise(res => {
let el;
if (isCss) {
el = document.createElement('link');
el.rel = 'stylesheet';
el.href = src;
} else {
el = document.createElement('script');
el.src = src;
}
document.documentElement.appendChild(el);
el.onload = el.onreadystatechange = function() {
if (
!this.readyState ||
this.readyState == 'loaded' ||
this.readyState == 'complete'
) {
res(true);
}
this.onload = this.onreadystatechange = null;
};
});
}
接下来就是我们的预览代码部分了
组件中引入
import LuckyExcel from "luckyexcel";
import axios from "axios";
import { asynLoad } from "@/utils/excel";//这个不能掉引入上面写的excel.js
if (e.fileType == "xlsx") {
this.dialogVisible = true;
this.titles = e.fileName + "文件预览";
this.excelShow = true;
this.wordShow = false;
const baseURL = "//cdn.jsdelivr.net/npm/luckysheet@latest/dist";
Promise.all([
asynLoad(`${baseURL}/plugins/css/pluginsCss.css`, true),
asynLoad(`${baseURL}/plugins/plugins.css`, true),
asynLoad(`${baseURL}/css/luckysheet.css`, true),
asynLoad(`${baseURL}/assets/iconfont/iconfont.css`, true),
asynLoad(`${baseURL}/plugins/js/plugin.js`),
asynLoad(`${baseURL}/luckysheet.umd.js`),
]).then(() => {
luckysheet = window.luckysheet;
this.getOriginFile(e); // 获取远端文件需要拿到完整的文件地址
}).catch((res) => {
console.log(res, "erro");
});
}
//下面还有两个不可缺少的方法
//url处理以及Blob的转换
getOriginFile(e) {
axios({
method: "get",
responseType: "blob",
//请求头,要自己写
headers: { "access-control-allow-origin": "*" },
//excel文件路径
url: 文件地址,//方法传入的参数里面要包含url完整的文件地址
}).then(({ data }) => {
const blob = new Blob([data]);
const file = new File([blob], this.fileName);
this.init(file); // 开始渲染
})
.catch((e) => {})
.finally(() => {});
},
//加载xls文件
init(file) {
luckysheet.destroy(); // 先销毁当前容器
LuckyExcel.transformExcelToLucky(file, (exportJson) => {
if (exportJson.sheets === null || !exportJson.sheets.length) {
this.$message.error("无法读取excel文件的内容,当前不支持xls文件!");
return;
}
luckysheet.create({
container: "luckysheet",
showinfobar: false,
lang: "zh",
data: exportJson.sheets,
title: exportJson.info.name,
userInfo: exportJson.info.name.creator,
container: "luckysheet", // 设定DOM容器的id
allowEdit: false, // 是否允许前台编辑
});
});
},
//弹窗关闭时候的销毁dom
closeDialog() {
this.excelShow = false;
this.wordShow = false;
},
关于excel的文件预览这边也有官方文档
https://mengshukeji.gitee.io/luckysheetdocs/zh/