在前端实现PDF、Execl、Word预览。暂时遇到的问题就是Word渲染时分页支持的不是很好。 当然还有其他的方案,比如onlyoffice不过这个需要单独部署服务。
实例
npm
npm install @vue-office/docx vue-demi #excel文档预览组件
npm install @vue-office/excel vue-demi #pdf文档预览组件
npm install @vue-office/pdf vue-demi
// 如果是vue2.6版本或以下还需要额外安装 @vue/composition-api
npm install @vue/composition-api
组件定义
js
<template>
<div class="file-preview-wrapper">
<vue-office-docx
v-if="docType === 'docx'"
:src="docContent"
class="file-body"
:options="docOptions"
@rendered="renderedHandler"
@error="errorHandler"
/>
<vue-office-excel
v-else-if="docType === 'xlsx'"
:src="docContent"
class="file-body"
@rendered="renderedHandler"
@error="errorHandler"
/>
<vue-office-pdf
v-else-if="docType === 'pdf'"
:src="docContent"
class="file-body"
@rendered="renderedHandler"
@error="errorHandler"
/>
<div v-else class="file-body">
<el-empty description="暂无内容" />
</div>
</div>
</template>
<script>
import VueOfficeDocx from '@vue-office/docx';
import '@vue-office/docx/lib/index.css';
import VueOfficeExcel from '@vue-office/excel';
import '@vue-office/excel/lib/index.css';
import VueOfficePdf from '@vue-office/pdf';
export default {
props: {
docType: {
required: true,
type: String,
validator(value) {
return ['docx', 'xlsx', 'pdf'].includes(value);
}
},
docContent: {
required: true,
type: String
}
},
components: {
VueOfficeDocx,
VueOfficeExcel,
VueOfficePdf
},
data() {
return {
docOptions: {
inWrapper: true, //enables rendering of wrapper around document content
ignoreWidth: true, //disables rendering width of page
ignoreHeight:true, //disables rendering height of page
ignoreFonts: true, //disables fonts rendering
breakPages: true, //enables page breaking on page breaks
ignoreLastRenderedPageBreak: false, //disables page breaking on lastRenderedPageBreak elements
experimental: true, //enables experimental features (tab stops calculation)
trimXmlDeclaration:true, //if true, xml declaration will be removed from xml documents before parsing
useBase64URL: true, //if true, images, fonts, etc. will be converted to base 64 URL, otherwise URL.createObjectURL is used
useMathMLPolyfill: true, //includes MathML polyfills for chrome, edge, etc.
showChanges: false, //enables experimental rendering of document changes (inserions/deletions)
debug: true //enables additional logging
}
};
},
methods: {
renderedHandler() {
console.log('渲染完成');
},
errorHandler() {
console.log('渲染失败');
}
}
};
</script>
<style lang="scss" scoped>
.file-preview-wrapper {
height: 100%;
width: 100%;
}
.file-body {
height: 100%;
}
</style>
组件使用
js
<template>
<FilePreview :docType="docType" :docContent="docContent" />
</template>
<script>
export default {
data(){
return {
docType:'docx',
docContent:'https://501351981.github.io/vue-office/examples/dist/#/docx'
}
},
created(){
//或者网络请求返回Arraybuffer
getXXXX().then(res=>{
let docData = new Blob([res], {
type: 'application/octet-stream'
});
const url = URL.createObjectURL(docData);
this.docContent = url;
})
}
}
</script>