vue 预览docx、pdf、xls、xlsx文件
vue预览docx、pdf、xls、xlsx文件office官方提供了office文件的预览,但是需要有域名与公网能访问到才行官网预览方式,src后加你的文件路径https://view.officeapps.live.com/op/view.aspx?src=官网内网预览插件(代码在文末)pdf预览插件(vue-pdf)安装npm install --save vue-pdf使用在需要使用的文件
·
vue 预览docx、pdf、xls、xlsx文件
office官方提供了office文件的预览,但是需要有域名与公网能访问到才行
官网预览方式,src后加你的文件路径
https://view.officeapps.live.com/op/view.aspx?src=
官网
内网预览插件(代码在文末)
pdf预览插件(vue-pdf)
安装
npm install --save vue-pdf
使用
在需要使用的文件中引入即可
import pdf from “vue-pdf”
样例
docx预览插件(mammoth)
该插件主要是把源文档转成了html,不支持doc文件
安装
npm install --save mammoth
使用
在需要使用的文件中引入即可
import mammoth from ‘mammoth’
xls、xlsx文件插件(xlsx)
安装
npm install xlsx -s
使用
同上,引入即可
import XLSX from “xlsx”
组件最终代码贴上
<template>
<div>
<el-dialog :visible="visible" :close-on-press-escape="false" :close-on-click-modal="false" append-to-body
@close="handleClose" width="800px" :fullscreen="fullscreen">
<template slot="title">
<div class="dialog-title ellipsis">
<div style="width: calc(100% - 20px);display: inline;">
文件预览({{ file.name }})
</div>
<div class="full-screen__menu" @click="fullscreen? fullscreen=false: fullscreen=true">
<i class="el-icon-full-screen"></i>
</div>
</div>
</template>
<div>
<!-- pdf预览 -->
<div v-if="fileType===1">
<div v-if="pdfData.pageCount>1">
<el-button type="primary" size="mini" @click="changePdfPage(0)" icon="el-icon-arrow-left"></el-button>
<span style="font-size: 14px;font-weight: 550;margin: 0 10px">{{ pdfData.currentPage }} / {{
pdfData.pageCount
}}</span>
<el-button type="primary" size="mini" @click="changePdfPage(1)" icon="el-icon-arrow-right"></el-button>
</div>
<div
:style="{height:fullscreen?(clientHeight-200)+'px':(clientHeight-400>800?800:clientHeight-400)+'px'}"
style="margin-top: 5px;border: 1px solid #a0a0a0;overflow:auto;">
<pdf
:src="pdfData.src"
:page="pdfData.currentPage"
@num-pages="pdfData.pageCount=$event"
@page-loaded="pdfData.currentPage=$event"
></pdf>
</div>
</div>
<!-- word文档预览 -->
<div v-if="fileType===2">
<div
:style="{height:fullscreen?(clientHeight-200)+'px':(clientHeight-400>800?800:clientHeight-400)+'px'}"
style="margin-top: 5px;border: 1px solid #a0a0a0;overflow: auto">
<div v-html="docHtml" style="padding: 10px 15px"></div>
</div>
</div>
<!-- Excel文档预览 -->
<div v-if="fileType===3">
<div class="tab">
<el-radio-group size="small" v-model="excel.sheetNameActive" @change="getSheetNameTable">
<el-radio-button v-for="(item,index) in excel.sheetNames" :key="index" :label="item"></el-radio-button>
</el-radio-group>
</div>
<div
:style="{height:fullscreen?(clientHeight-200)+'px':(clientHeight-400>800?800:clientHeight-400)+'px'}"
style="margin-top: 5px;border: 1px solid #a0a0a0;overflow:auto;">
<div v-html="excel.SheetActiveTable" style="padding: 10px 15px"></div>
</div>
</div>
<div v-if="!fileType" style="line-height: 50px;text-align: center;font-size: 16px">
文件格式不支持,仅支持pdf,docx,xlsx,xls文件预览
</div>
</div>
<div style="text-align: right;margin-top: 5px">
<el-button size="small" @click="handleClose" class="raise">关闭</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import XLSX from "xlsx"
import pdf from "vue-pdf"
import mammoth from 'mammoth'
export default {
name: "officePreview",
props: {
visible: {
type: Boolean,
default: false
},
// file:{name:'',url:''}
file: {
type: Object,
default: () => {
return {}
}
},
// 弹窗高度
clientHeight: {
type: Number,
default: 600
},
// 基础链接
baseURL: {
type: String,
default: undefined
}
},
data() {
return {
// 全屏
fullscreen: false,
// 文件类型
fileType: 1,
// pdf数据
pdfData: {
// 当前页
currentPage: 1,
// pdf文件总页数
pageCount: 0,
//
src: ""
},
docHtml: "",
// 空文件提示信息
emptyTips: '暂无内容',
// Excel文档数据
excel: {
// 数据
workbook: {},
// 表名称集合
sheetNames: [],
// 激活项
sheetNameActive: "",
// 当前激活表格
SheetActiveTable: ""
}
}
},
methods: {
handleClose() {
this.$emit("update:visible", false)
},
/**
* 切换pdf显示页
* @param command
*/
changePdfPage(command) {
if (command === 0) {
if (this.pdfData.currentPage > 1) {
this.pdfData.currentPage--
}
} else if (command === 1) {
if (this.pdfData.currentPage < this.pdfData.pageCount) {
this.pdfData.currentPage++
}
}
},
/**
* 获取文件类型
* @return {null|number}
*/
getFileType() {
if (!this.file) {
return null
}
let fileName = this.file.name.lastIndexOf(".");//取到文件名开始到最后一个点的长度
let fileNameLength = this.file.name.length;//取到文件名长度
let fileFormat = this.file.name.substring(fileName + 1, fileNameLength);//截
console.log(fileFormat)
if (fileFormat.toLowerCase() === "pdf") {
return 1
} else if (fileFormat.toLowerCase() === "docx") {
return 2
} else if (fileFormat.toLowerCase() === "xlsx" || fileFormat.toLowerCase() === "xls") {
return 3
}
return null
},
/**
* pdf预览
*/
initPdf() {
// this.pdfData.src = pdf.createLoadingTask(this.$baseURL + this.file.url)
try {
// 加载
let _this = this
const xhr = new XMLHttpRequest();
xhr.open('get', this.baseURL + this.file.url, true);
xhr.responseType = 'blob';
xhr.onload = function () {
if (xhr.status === 200) {
_this.pdfData.src = _this.getObjectURL(xhr.response)
} else if (xhr.status === 404) {
_this.$error({message: "文件不存在"})
} else {
_this.$error({message: "读取服务器文档异常"})
}
}
xhr.onerror = function () {
_this.$error({message: "访问服务器异常,请检查访问链接是否正常"})
}
xhr.send();
} catch (e) {
console.log(e)
}
},
/**
* 将返回的流数据转换为url
* @param file 文件流
*/
getObjectURL(file) {
let url = null;
if (window.createObjectURL !== undefined) { // basic
url = window.createObjectURL(file);
} else if (window.webkitURL !== undefined) { // webkit or chrome
try {
url = window.webkitURL.createObjectURL(file);
} catch (error) {
}
} else if (window.URL !== undefined) { // mozilla(firefox)
try {
url = window.URL.createObjectURL(file);
} catch (error) {
console.log(error)
}
}
return url;
},
/**
* docx文件预览
*/
initDocPreview() {
// 请求文件流
try {
let _this = this
const xhr = new XMLHttpRequest();
xhr.open('get', this.baseURL + this.file.url, true);
xhr.responseType = 'arraybuffer';
xhr.onload = function () {
if (xhr.status === 200) {
mammoth.convertToHtml({arrayBuffer: new Uint8Array(xhr.response)}).then(function (resultObject) {
_this.docHtml = resultObject.value
})
} else if (xhr.status === 404) {
_this.$error({message: "文件不存在"})
} else {
_this.$error({message: "读取服务器文档异常"})
}
}
xhr.onerror = function () {
_this.$error({message: "访问服务器异常,请检查访问链接是否正常"})
}
xhr.send();
} catch (e) {
this.docHtml = '<h1 style="text-align: center">' + this.emptyTips + '</h1>'
}
},
/**
* 表格数据预览
*/
initExcelPreview() {
try {
let xhr = new XMLHttpRequest()
xhr.open('get', this.baseURL + this.file.url, true)
xhr.responseType = 'arraybuffer'
const _this = this
xhr.onload = function (e) {
if (xhr.status === 200) {
const data = new Uint8Array(xhr.response)
const workbook = XLSX.read(data, {type: 'array'})
const sheetNames = workbook.SheetNames // 工作表名称集合
_this.excel.workbook = workbook
_this.excel.sheetNames = sheetNames
_this.excel.sheetNameActive = sheetNames[0]
_this.getSheetNameTable(sheetNames[0])
} else if (xhr.status === 404) {
_this.$error({message: "文件不存在"})
} else {
_this.$error({message: "读取服务器文档异常"})
}
}
xhr.onerror = function () {
_this.$error({message: "访问服务器异常,请检查访问链接是否正常"})
}
xhr.send()
} catch (e) {
console.log(e)
}
},
/**
* 根据工作表名称获取数据
* @param sheetName
*/
getSheetNameTable(sheetName) {
try {
// 获取当前工作表的数据
const worksheet = this.excel.workbook.Sheets[sheetName]
// 转换为数据 1.json数据有些问题,2.如果是html那么样式需修改
let htmlData = XLSX.utils.sheet_to_html(worksheet, {header: '', footer: ''})
htmlData = htmlData === '' ? htmlData : htmlData.replace(/<table/, '<table class="default-table" border="1px solid #ccc" cellpadding="0" cellspacing="0"')
// 第一行进行改颜色
htmlData = htmlData === '' ? htmlData : htmlData.replace(/<tr/, '<tr style="background:#b4c9e8"')
this.excel.SheetActiveTable = htmlData
} catch (e) {
// 如果工作表没有数据则到这里来处理
this.excel.SheetActiveTable = '<h4 style="text-align: center">' + this.emptyTips + '</h4>'
}
},
},
created() {
this.fileType = this.getFileType()
if (this.fileType === 1) {
this.initPdf()
}
if (this.fileType === 2) {
this.initDocPreview()
}
if (this.fileType === 3) {
this.initExcelPreview()
}
},
components: {
pdf
}
}
</script>
<style scoped>
.dialog-title {
text-align: center;
display: flex;
font-size: 18px;
width: calc(100% - 30px);
}
.full-screen__menu {
font-size: 16px;
display: inline;
}
.full-screen__menu:hover {
font-size: 16px;
color: #2D8CF0;
}
</style>
<style>
table.default-table {
/* -moz-border-radius: 5px;
-webkit-border-radius:5px;
border-radius:5px; */
width: 100%;
border: solid #333;
border-width: 1px 0px 0px 1px;
font-size: 16px;
border-collapse: collapse;
border-spacing: 0;
}
table.default-table tbody tr {
height: 20px;
line-height: 20px;
white-space: nowrap;
}
table.default-table tbody tr:hover {
background-color: #eee;
}
table.default-table tbody tr th, table.default-table tbody tr td {
padding: 3px 5px;
text-align: left;
/* border: 1px solid #ddd; */
border: solid #333;
border-width: 0px 1px 1px 0px;
white-space: nowrap;
}
table.default-table tbody tr th {
font-weight: bold;
text-align: center;
}
table.default-table tbody tr td a:hover {
color: #0080c0;
}
</style>
组件使用
将组件导入要使用的文件中即可
import officePreview from "../../../components/officePreview";
components: {
officePreview
}
<office-preview :visible.sync="previewVisible" v-if="previewVisible" :client-height="clientHeight"
:file="previewFile" :base-u-r-l="officeURL"></office-preview>
更多推荐
已为社区贡献5条内容
所有评论(0)