目录
1、导入控件
//预览docx
npm install docx-preview --save
npm install jszip --save//图片缩放空控件
npm install vue-photo-preview --save
2、创建组件
<template>
<!-- 图片、pdf、docx 预览
"docx-preview": "^0.1.4",
"jszip": "^3.10.0",-->
<div>
<a-modal title="文件预览" :visible="showDoc || showPdf || showImg" :maskClosable="false" @cancel="cancel"
width="750px">
<template slot="closeIcon">
<my-icon icon="close-circle" class="closeIcon"/>
</template>
<template slot="footer">
<div v-if="showPdf" class="pdf-layout-page">
<my-button @click="changePdfPage(0)" :disabled="currentPage===1" name="上一页"/>
{{currentPage}} / {{pageCount}}
<my-button @click="changePdfPage(1)" :disabled="currentPage===pageCount" name="下一页"/>
</div>
<my-button name="取消" @click="cancel"/>
</template>
<div class="modal-body form">
<div v-if="showImg">
<img :src="images" preview="1" preview-text="" style="width:100%"/>
</div>
<div v-show="showDoc" ref="word">
<iframe v-if="fileUrl" frameborder="0"
:src="fileUrl"
width='100%'
height="100%">
</iframe>
</div>
<div v-show="showPdf" class="pdf-layout" id="top">
<pdf-view
ref="pdf"
:src="pdfPath"
:page="currentPage"
@num-pages="pageCount=$event"
@page-loaded="currentPage=$event"
@loaded="loadPdfHandler"/>
</div>
</div>
</a-modal>
</div>
</template>
<script>
import pdfView from 'vue-pdf'
import axios from 'axios'
const docxPre = require('docx-preview')
window.JSZip = require('jszip')
export default {
name: 'FilePreview',
components: { pdfView },
data() {
return {
showDoc: false,//判断如果是否为word文件显示
showPdf: false,//判断如果是否为pdf文件显示
showImg: false,//判断如果是否为图片显示
fileUrl: '',//pdf链接
images: '',//图片链接
currentPage: 0, // pdf文件页码
pageCount: 0, // pdf文件总页数
}
},
methods: {
showView(filePath) {
let that = this
let type = filePath.split('.')[filePath.split('.').length - 1]
if (type === 'jpg' || type === 'png' || type === 'jpeg') {
that.images = filePath
that.showImg = true
} else if (type === 'pdf') {
that.loadPdfHandler()//重置pdf第一页展示
that.pdfPath = filePath
that.showPdf = true
} else if (type === 'doc') {//word预览
that.fileUrl = 'https://view.officeapps.live.com/op/view.aspx?src=' + filePath
that.showDoc = true
} else if (type === 'docx') {//word预览
that.showDoc = true
that.previewWord(filePath)
}
},
// 后端返回二进制流
previewWord(filePath) {
let that = this
// 这里需要提起打开弹窗,因为有时很找不到word的ref 会报错
axios({
method: 'get',
responseType: 'blob', // 因为是流文件,所以要指定blob类型
url: filePath
}).then(({ data }) => {
docxPre.renderAsync(data, this.$refs.word)
})
},
//pdf上一页下一页操作
changePdfPage(val) {
if (val === 0 && this.currentPage > 1) {
this.currentPage--
}
if (val === 1 && this.currentPage < this.pageCount) {
this.currentPage++
this.top()
}
},
top() {
document.querySelector('#top').scrollIntoView(true)
},
// pdf加载时
loadPdfHandler(e) {
this.currentPage = 1 // 加载的时候先加载第一页
},
cancel() {
this.showDoc = false//判断如果是否为word文件显示
this.showPdf = false//判断如果是否为pdf文件显示
this.showImg = false//判断如果是否为图片显示
}
}
}
</script>
<style lang="less" scoped>
.form {
height: 600px;
overflow: auto;
}
.pdf-layout-page {
left: 30%;
margin: auto;
display: inline-block;
text-align: center;
font-size: 14px;
position: absolute
}
</style>
3、使用组件
<template>
<div>
<file-preview ref="filePreview"/>
</div>
</template>
<script>
//组件中引入
import FilePreview from '@/components/FilePreview/index'
export default {
components: { FilePreview },
methods: {
lookFile() {
this.$refs.filePreview.showView(fileUrl)
}
}
}
</script>
docx-preview组件在解析doc文件会失败,docx可以;没搞清楚是为什么
注:示例中使用的ui框架是 Ant Design Vue ,使用的控件可替换成相应项目的ui框架