vue-office 官网
一、安装
1) 分开安装
# docx 文档预览组件
npm install @vue-office/docx vue-demi@0.14.6
# excel 文档预览组件
npm install @vue-office/excel vue-demi@0.14.6
# pdf 文档预览组件
npm install @vue-office/pdf vue-demi@0.14.6
vue-demi@0.14.6; 其中 @0.14.6 为版本号,可以不加,默认下载最新版。
如果是 vue2.6 版本或以下还需要额外安装 @vue/composition-api
npm install @vue/composition-api
2) 全部安装
npm install --save @vue-office/docx @vue-office/excel @vue-office/pdf vue-demi@0.14.6
二、使用
1) 组件封装
① 创建文件 @/components/FileView/index.vue
我这里预览 PDF 时用的 PDFJS ,因为功能更全面。你们不用的话可以去掉,或者自行比较一下。
<script setup lang='ts'>
import VueOfficeDocx from '@vue-office/docx'
import VueOfficeExcel from '@vue-office/excel'
import VueOfficePdf from '@vue-office/pdf'
import PDF from "@/components/FileView/PDF.vue"
import '@vue-office/docx/lib/index.css'
import '@vue-office/excel/lib/index.css'
const { data } = defineProps<{ data: {
type: string, // 附件类型,也可以从 src 上截取
src: string
} }>()
let loading = ref(false)
let options={
xls: data.type === "xls" ? true : false , //预览xlsx文件设为false;预览xls文件设为true
minColLength: 0, // excel最少渲染多少列,如果想实现xlsx文件内容有几列,就渲染几列,可以将此值设置为0.
minRowLength: 0, // excel最少渲染多少行,如果想实现根据xlsx实际函数渲染,可以将此值设置为0.
widthOffset: 10, //如果渲染出来的结果感觉单元格宽度不够,可以在默认渲染的列表宽度上再加 Npx宽
heightOffset: 10, //在默认渲染的列表高度上再加 Npx高
beforeTransformData: (workbookData) => {return workbookData}, //底层通过exceljs获取excel文件内容,通过该钩子函数,可以对获取的excel文件内容进行修改,比如某个单元格的数据显示不正确,可以在此自行修改每个单元格的value值。
transformData: (workbookData) => {return workbookData}, //将获取到的excel数据进行处理之后且渲染到页面之前,可通过transformData对即将渲染的数据及样式进行修改,此时每个单元格的text值就是即将渲染到页面上的内容
}
const renderedHandler = () => {
loading.value = false;
console.log("渲染完成")
}
const errorHandler = () => {
loading.value = false;
console.log("渲染失败")
}
let loadingList = ["docx","xlsx","xls"]
if (loadingList.some(a=> a === data.type)) {
loading.value = true;
}
</script>
<template>
<div v-loading="loading" class="box">
<vue-office-docx
v-if="data.type === 'docx'"
:src="data.src"
style="width: 100%;height: 100%"
@rendered="renderedHandler"
@error="errorHandler"
/>
<vue-office-excel
v-else-if="data.type === 'xlsx' || data.type === 'xls'"
:src="data.src"
:options="options"
style="height: 72vh;width: 100%"
@rendered="renderedHandler"
@error="errorHandler"
/>
<!-- <vue-office-pdf
v-else-if="data.type === 'pdf'"
:src="data.src"
@rendered="renderedHandler"
@error="errorHandler"
/> -->
<PDF :url="data.src" v-else-if="data.type === 'pdf'" style="height: 72vh;width: 100%" />
<div v-else-if="data.type ==='jpg' || data.type === 'png' || data.type === 'jpeg'" class="h-100 w-100 con">
<img :src="data.src">
</div>
<div v-else>
<el-empty description="暂不支持该文件格式" />
</div>
</div>
</template>
<style scoped lang='scss'>
.box {
width: 100%;
height: 75vh;
height: 100%;
background-color: #fff;
box-sizing: border-box;
overflow: auto;
}
.con{
display: flex;
justify-content: center;
align-items: center;
img{
max-width: 100%;
max-height: 100%;
}
}
</style>
② 创建文件 @/components/FileView/PDF.vue
此文件主要是通过 PDFJS 预览 PDf ,没用到的可以不用管。
详细使用可以参考我的另一篇文章:记录一下使用PDFJS遇到的坑 。
<script setup lang="ts">
import { onMounted, ref } from 'vue';
interface Props {
url: string; // pdf文件地址
}
const props = defineProps<Props>();
const pdfUrl = ref(''); // pdf文件地址
const fileUrl = '/fileView/web/viewer.html?file='; // pdfjs文件地址
onMounted(() => {
// encodeURIComponent() 函数可把字符串作为 URI 组件进行编码。
// 核心就是将 iframe 的 src 属性设置为 pdfjs 的地址,然后将 pdf 文件的地址作为参数传递给 pdfjs
// 例如:http://localhost:8080/pdfjs-4.0.189-dist/web/viewer.html?file=http://localhost:8080/pdf/test.pdf
pdfUrl.value = fileUrl + encodeURIComponent(props.url);
});
</script>
<template>
<div class="container">
<iframe :src="pdfUrl" width="100%" height="100%"></iframe>
</div>
</template>
<style scoped lang="scss">
.container {
width: 100%;
height: 100%;
}
</style>
2) 调用组件
import fileViewModal from "@/components/FileView/index.vue"
<fileViewModal
:data="{
src: 'https://xxx',
type: 'pdf'
}"
/>
三、非Vue框架文件预览
1) 安装
# docx 文件预览库
npm i @js-preview/docx
# excel 文件预览库
npm i @js-preview/excel
# pdf 文件预览库
npm i @js-preview/pdf
全部安装:
npm install @js-preview/docx @js-preview/excel @js-preview/pdf
2) 预览
① docx 文件预览
import jsPreviewDocx from "@js-preview/docx";
import '@js-preview/docx/lib/index.css'
//初始化时指明要挂载的父元素Dom节点
const myDocxPreviewer = jsPreviewDocx.init(document.getElementById('docx'));
//传递要预览的文件地址即可
myDocxPreviewer.preview('https://501351981.github.io/vue-office/examples/dist/static/test-files/test.docx').then(res=>{
console.log('预览完成');
}).catch(e=>{
console.log('预览失败', e);
})
② excel 文件预览
import jsPreviewExcel from "@js-preview/excel";
import '@js-preview/excel/lib/index.css';
const myExcelPreviewer = jsPreviewExcel.init(document.getElementById('excel'));
myExcelPreviewer.preview('https://501351981.github.io/vue-office/examples/dist/static/test-files/test.xlsx').then(res=>{
console.log('预览完成');
}).catch(e=>{
console.log('预览失败', e);
})
③ pdf 文件预览
import jsPreviewPdf from "@js-preview/pdf";
const myPdfPreviewer = jsPreviewPdf.init(document.getElementById('pdf'), {
onError: (e)=>{
console.log('发生错误', e)
},
onRendered: ()=>{
console.log('渲染完成')
}
});
myPdfPreviewer.preview('https://501351981.github.io/vue-office/examples/dist/static/test-files/test.pdf');
四、注意
-
vue-office不支持doc文件的预览(如果需要预览doc,请更换其他组件或者找后端帮忙转换成docx)
-
如果后端给的不是CDN地址,而是一些POST接口,该接口返回二进制流,则可以调用接口获取文件的ArrayBuffer数据,传递给src属性。
<script>
fetch('你的API文件地址', {
method: 'post'
}).then(res=>{
//读取文件的arrayBuffer
res.arrayBuffer().then(res=>{
data.src = res
})
})
</script>
-
对 xls 文件进行预览时,必须设置 options={ xls: true }