vue 在线预览 word ,Excel,pdf,图片 数据流 内网文件流 亲测有效(word 目前支持docx文件以及doc文件(doc需要后端处理))
·
注:doc转 docx后端转数据流 谷歌 114 版本以上会解析错误!
如果是需要更好的体验:可以使用 kkFileView - 在线文件预览
需要后端在服务器部署一个服务 之后返回地址前端进行直接在线访问;(支持内网哦)
需求:在线预览文件(doc,docx,xls,xlsx,img,pdf)其他类型下载
如果你要是公网 那直接参考在线office 引入url地址 直接预览(本文是返回数据流 不是公网)
效果图:
xls :代码效果
xls:office效果
doc :代码效果
doc :office效果
pdf 效果
图片效果
pdf 直接用的浏览器自带的
excel 插件 xlsx
docx 插件 docx-preview
npm install xlsx --save
npm install docx-preview --save
也是查阅了好多东西也借鉴了许多人的代码,亲测有效! 拿过去换地址 直接就能用
html 代码
<template>
<div class="viewItemFile">
<!-- 预览文件 -->
<el-dialog
width="100%"
class="viewItemFileDialog"
title="预 览"
:visible.sync="dialogVisible"
:before-close="innerhandleClose"
:close-on-click-modal="false"
:close-on-press-escape="false"
>
//判断类型
<div class="image" v-if="type == 'image'">
<div>
<el-image :src="imgUrl" :preview-src-list="srcList"> </el-image>
</div>
</div>
<div class="docWrap" v-if="type == 'doc'">
<!-- 预览文件的地方(用于渲染) -->
<div ref="file"></div>
</div>
<div v-if="type == 'xls'">
<div class="excel-view-container">
<div id="excelView" v-html="excelView"></div>
</div>
</div>
// pdf用嵌套的iframe
<div v-if="type == 'pdf'">
<iframe
:src="pdfurl"
type="application/x-google-chrome-pdf"
width="100%"
height="100%"
/>
</div>
</el-dialog>
</div>
</template>
script
methods:{
// 前一个页面调用的init 我在前一个页面根据文件名字后缀已经判断是什么类型的文件了
init(file, type) {
this.type = type;
if (type == "image") {
axios
.request({
method: "GET", //这个不解释了吧
url: '后端接口', //路径
responseType: "blob", //告诉服务器想到的响应格式
headers: {
Accept: "application/octet-stream",
},
})
.then((res) => {
console.log(res);
if (res) {
let blob = new Blob([res.data], { type: "image/jpeg" });
const imageUrl = URL.createObjectURL(blob);
this.imgUrl = imageUrl;
this.srcList = [imageUrl],;
that.loading = true;
} else {
that.$notify.error({ title: "失败", message: "接口请求失败" });
that.loading = false;
}
})
.catch(function (error) {
that.$notify.error({ title: "失败", message: "接口请求失败" });
console.log(error);
that.loading = false;
});
} else if (type == "pdf") {
axios
.request({
method: "GET", //这个不解释了吧
url: '后端地址'//路径
responseType: "blob", //告诉服务器想到的响应格式
headers: {
"Content-Type": "application/pdf;charset=UTF-8",
},
})
.then((res) => {
console.log(res);
if (res) {
let blob = new Blob([res.data], { type: "application/pdf" });
const url = URL.createObjectURL(blob);
console.log(url);
that.loading = false;
this.pdfurl = url;
} else {
that.$notify.error({ title: "失败", message: "接口请求失败" });
that.loading = false;
}
})
.catch(function (error) {
that.$notify.error({ title: "失败", message: "接口请求失败" });
console.log(error);
that.loading = false;
});
} else if (type == "xls") {
//表格
var that = this;
axios
.request({
method: "GET", //这个不解释了吧
url: '后端地址', //路径
responseType: "arraybuffer", //告诉服务器想到的响应格式
headers: {
"Content-Type":
"application/vnd.ms-excel;application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
},
})
.then((res) => {
console.log(res);
if (res) {
const workbook = XLSX.read(new Uint8Array(res.data), {
type: "array",
}); // 解析数据
const worksheet = workbook.Sheets[workbook.SheetNames[0]]; // workbook.SheetNames 下存的是该文件每个工作表名字,这里取出第一个工作表
this.excelView = XLSX.utils.sheet_to_html(worksheet); // 渲染
this.$nextTick(function () {
// DOM加载完毕后执行,解决HTMLConnection有内容但是length为0问题。
this.setStyle4ExcelHtml();
});
} else {
that.$notify.error({ title: "失败", message: "接口请求失败" });
that.loading = false;
}
})
.catch(function (error) {
that.$notify.error({ title: "失败", message: "接口请求失败" });
console.log(error);
that.loading = false;
});
} else if (type == "doc") {
// word
var that = this;
axios
.request({
method: "GET", //这个不解释了吧
url: '后端地址' //路径
responseType: "blob", //告诉服务器想到的响应格式
})
.then((res) => {
console.log(res);
if (res) {
let docx = require("docx-preview");
docx.renderAsync(res.data, this.$refs.file);
} else {
that.$notify.error({ title: "失败", message: "接口请求失败" });
that.loading = false;
}
})
.catch(function (error) {
that.$notify.error({ title: "失败", message: "接口请求失败" });
console.log(error);
that.loading = false;
});
}
this.dialogVisible = true;
},
// 设置Excel转成HTML后的样式
setStyle4ExcelHtml() {
const excelViewDOM = document.getElementById("excelView");
if (excelViewDOM) {
const excelViewTDNodes = excelViewDOM.getElementsByTagName("td"); // 获取的是HTMLConnection
if (excelViewTDNodes) {
const excelViewTDArr = Array.prototype.slice.call(excelViewTDNodes);
for (const i in excelViewTDArr) {
const id = excelViewTDArr[i].id; // 默认生成的id格式为sjs-A1、sjs-A2......
if (id) {
const idNum = id.replace(/[^0-9]/gi, ""); // 提取id中的数字,即行号
if (idNum && (idNum === "1" || idNum === 1)) {
// 第一行标题行
excelViewTDArr[i].classList.add("class4Title");
}
if (idNum && (idNum === "2" || idNum === 2)) {
// 第二行表头行
excelViewTDArr[i].classList.add("class4TableTh");
}
}
}
}
}
},
}
css 有需要的 自行添加
<style lang="scss" scoped>
.viewItemFile {
.image {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
div {
height: 600px;
width: 600px;
}
}
.divContent {
display: flex;
align-items: center;
justify-content: center;
}
/deep/ .el-dialog {
margin: 0 !important;
height: 100vh !important;
.el-dialog__footer {
margin-bottom: 30px;
padding: 0px;
}
}
/deep/ .el-dialog__body {
height: 96%;
width: 100%;
padding: 0;
overflow: auto;
}
}
.viewItemFile {
/deep/ table {
width: 100% !important;
border-collapse: collapse !important;
border-spacing: 0 !important;
text-align: center !important;
border: 0px !important;
overflow-x: auto !important;
}
/deep/ table tr td {
/* border: 1px solid gray !important; */
border-right: 1px solid gray !important;
border-bottom: 1px solid gray !important;
width: 300px !important;
height: 33px !important;
}
/**整体样式 */
/deep/ .excel-view-container {
background-color: #ffffff;
}
/**标题样式 */
/deep/ .class4Title {
font-size: 22px !important;
font-weight: bold !important;
padding: 10px !important;
}
/**表格表头样式 */
/deep/ .class4TableTh {
/* font-size: 14px !important; */
font-weight: bold !important;
padding: 2px !important;
background-color: #ccc !important;
}
}
</style>
<style lang="scss">
.viewItemFileDialog {
overflow: hidden;
.el-dialog__header {
padding: 10px 20px 10px;
background-color: #19a199;
}
.el-dialog__header .el-dialog__title {
font-size: 15px;
color: #ffffff;
font-weight: 700;
}
.dialog-footer {
display: flex;
justify-content: center;
}
.search-btn {
background: #19a8a6;
color: white;
border: none;
height: 30px;
padding: 0px 20px;
}
.el-dialog__headerbtn .el-dialog__close {
color: #ffffff;
}
.well {
display: block;
background-color: #f2f2f2;
border: 1px solid #ccc;
margin: 0px;
width: 100%;
height: 100%;
overflow: auto;
}
}
</style>
文件流
excel 文件流 其他的就不都发了
doc 文件需要后端转成docx文件流返回 之后直接用docx插件搞定!
参考地址:java doc转docx
更多推荐
已为社区贡献5条内容
所有评论(0)