如果项目是外网,iframe + 微软提供的免费在线预览office接口 https://view.officeapps.live.com/op/view.aspx?src=http://static.shanhuxueyuan.com/test6.docx 实现以上类型文件的预览(还有doc/ppt)等
如果项目是内网,没做内网穿透,那就只能装插件
xls/xlsx/docx
用的 vue-office,安装使用看官网介绍,非常详细简洁,但是注意xls加载不了excel样式
1.xls
2.xlsx
3.docx
pdf/txt
vue-office也有pdf插件@vue-office/pdf,不过我用了iframe实现,因为浏览器自带的PDF功能挺丰富,还能加载.txt文件
pptx
使用PPTXjs实现
- 点此下载 PPTXjs压缩包,解压后放在public目录下
- 在index.html中引入css/js
css
<link rel="stylesheet" href="/PPTXjs/css/pptxjs.css"> <link rel="stylesheet" href="/PPTXjs/css/nv.d3.min.css"> <!-- for charts graphs -->
复制
js
<script type="text/javascript" src="/PPTXjs/js/jquery-1.11.3.min.js"></script> <script type="text/javascript" src="/PPTXjs/js/jszip.min.js"></script> <!-- v2.. , NOT v.3.. --> <script type="text/javascript" src="/PPTXjs/js/filereader.js"></script> <!--https://github.com/meshesha/filereader.js --> <script type="text/javascript" src="/PPTXjs/js/d3.min.js"></script> <!-- for charts graphs --> <script type="text/javascript" src="/PPTXjs/js/nv.d3.min.js"></script> <!-- for charts graphs --> <script type="text/javascript" src="/PPTXjs/js/pptxjs.js"></script> <script type="text/javascript" src="/PPTXjs/js/divs2slides.js"></script> <!-- for slide show -->
复制
- iframe获取动态文件地址
在PPTXjs/index.html页面,获取传给iframe的动态文件地址
代码
<template> <el-dialog v-loading="loading" :title="dialogTitle" fullscreen lock-scroll center ref="dialog" custom-class="dialog" :close-on-press-escape="false" :visible.sync="dialogVisible" :before-close="handleClose" > <!-- <vue-office-pdf v-if="['pdf'].includes(fileType)" :src="fileUrl" :style="{ height: bodyHeight + 'px' }" @rendered="renderedHandler('pdf')" @error="errorHandler('pdf')" /> --> <vue-office-docx v-if="['doc', 'docx'].includes(fileType)" :src="fileUrl" :style="{ height: bodyHeight + 'px' }" @rendered="renderedHandler('doc')" @error="errorHandler('doc')" /> <vue-office-excel v-else-if="['xls', 'xlsx'].includes(fileType)" :src="fileUrl" :options="excelOptions" :style="{ height: bodyHeight + 'px' }" @rendered="renderedHandler('xls')" @error="errorHandler('xls')" /> <iframe v-else-if="['pdf', 'txt', 'pptx'].includes(fileType)" id="iframe" :src=" ['pdf', 'txt'].includes(fileType) ? fileUrl : `/PPTXjs-master/index.html?file=` + fileUrl " :style="{ height: bodyHeight + 'px' }" ></iframe> <div slot="footer"> <el-button type="primary" round @click="handleClose">关闭</el-button> </div> </el-dialog> </template> <script> //引入VueOfficeDocx组件 import VueOfficeDocx from "@vue-office/docx"; //引入相关样式 import "@vue-office/docx/lib/index.css"; //引入VueOfficeExcel组件; import VueOfficeExcel from "@vue-office/excel"; //引入相关样式 import "@vue-office/excel/lib/index.css"; //引入VueOfficePdf组件 // import VueOfficePdf from "@vue-office/pdf"; export default { components: { VueOfficeDocx, VueOfficeExcel, // VueOfficePdf, }, data() { return { dialogVisible: false, dialogTitle: "", loading: false, frontUrl: process.env.VUE_APP_BASE_API + "/file/preOrDown?filePath=", behindtUrl: "&type=0", // excel: "http://static.shanhuxueyuan.com/demo/excel.xlsx", //设置文档地址 // pdf: "http://static.shanhuxueyuan.com/test.pdf", //设置文档地址 // docx: "http://static.shanhuxueyuan.com/test6.docx", //设置文档网络地址,可以是相对地址 // https://www.hengdianworld.com/DownloadFile/横店影视城游览手册.docx docOptions: { className: "docx", //class name/prefix for default and document style classes inWrapper: true, //enables rendering of wrapper around document content ignoreWidth: false, //disables rendering width of page ignoreHeight: false, //disables rendering height of page ignoreFonts: false, //disables fonts rendering breakPages: true, //enables page breaking on page breaks ignoreLastRenderedPageBreak: false, //disables page breaking on lastRenderedPageBreak elements experimental: false, //enables experimental features (tab stops calculation) trimXmlDeclaration: true, //if true, xml declaration will be removed from xml documents before parsing useBase64URL: false, //if true, images, fonts, etc. will be converted to base 64 URL, otherwise URL.createObjectURL is used useMathMLPolyfill: false, //includes MathML polyfills for chrome, edge, etc. showChanges: false, //enables experimental rendering of document changes (inserions/deletions) debug: false, //enables additional logging }, excelOptions: { xls: true, //预览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值就是即将渲染到页面上的内容 }, fileUrl: "", fileType: "", bodyHeight: "", }; }, methods: { init(row) { this.loading = true; this.dialogVisible = true; this.dialogTitle = row.originalTitle; this.fileUrl = this.frontUrl + row.filePath + this.behindtUrl; this.fileType = row.filePath.split(".")[1]; console.log("fileType", this.fileType); console.log("fileUrl", this.fileUrl); this.excelOptions.xls = this.fileType == "xls" ? true : false; this.$nextTick(() => { const dialog = document.getElementsByClassName("dialog")[0]; const dialogChildren = dialog.children; const headerHeight = dialogChildren[0].offsetHeight; const footerHeight = dialogChildren[2].offsetHeight; this.bodyHeight = dialog.offsetHeight - headerHeight - footerHeight; if (["pdf", "txt", "pptx"].includes(this.fileType)) { const iframe = document.getElementById("iframe"); // attachEvent为IE专用方法 if (iframe.attachEvent) { iframe.attachEvent("onload", function () { console.log("iframe is now loaded."); this.loading = false; }); } else { iframe.onload = () => { console.log("iframe is now loaded."); this.loading = false; }; } } }); }, renderedHandler(type) { console.log("渲染完成", type); this.loading = false; }, errorHandler(type) { console.log("渲染失败", type); this.loading = false; }, handleClose() { this.dialogVisible = false; this.dialogTitle = ""; this.fileUrl = ""; this.fileType = ""; this.bodyHeight = ""; }, }, }; </script> <style lang="scss" scoped> ::v-deep { .el-dialog--center .el-dialog__body { padding: 0; } } iframe { width: 100%; display: block; } </style>
复制
参考
https://blog.csdn.net/q2qwert/article/details/130905525
https://blog.csdn.net/KK_vicent/article/details/130827910