最近公司项目中要实现 文档上传之后要在线预览 :当时心想这不是挺简单的吗 嘿嘿!直接用在线的 XDOC 就能实现!后来说客户那边是内网…………哎
外网预览
访问网址:/xdoc?_func=to&_format=html&_cache=1&_xdoc=文件地址
内网预览
其实就是将后台传的二进制文件流 转化为html 元素
前台代码
说明:① excel 需要安装 xlsx : npm install --save xlsx② word需要安装 mammoth : npm install --save mammoth
引入依赖:import mammoth from "mammoth";import XLSX from 'xlsx'
<!-- 预览模式框 --><Modal v-model="modalPreview" fullscreen title="预览" @on-cancel="cancelPreview"><!-- excel --><div v-if="previewType==='xls'||previewType==='xlsx'"><div class="tableExcel" v-html="excelHtml"></div></div><!-- word --><div v-else-if="previewType==='doc'||previewType==='docx'"><div class="word" id="wordView"/></div><div slot="footer"></div></Modal>
属性:data() {return {previewType:null,//预览类型excelHtml:'',wordHtml:'',};},
接口api : 我这里只写excel了 别忘了调用接口的时候 引用api/*** 预览excel*/export function getExcel (params) {return request({url: '/getExcel',method: 'post',params: params,responseType:'arraybuffer'})}
方法:/***********************************附件预览***********************************//********** 预览excel ***************/previewExcel:function(url){// url 是上传成功的文件地址this.previewType=url.substr(url.indexOf(".")+1);;this.modalPreview=true;//访问后台接口getExcel({'url':url}).then(res => {var data = new Uint8Array(res)var workbook = XLSX.read(data, {type: 'array'})this.excelHtml='';for(var i=0;i<workbook.SheetNames.length;i++){const exlname = workbook.SheetNames[i];this.excelHtml+='<h4 style="padding-left:10px;font-size:13px;">'+exlname+'</h4>'+''+XLSX.utils.sheet_to_html(workbook.Sheets[exlname])+'<br>'}})},/********** 预览word ***************/previewWord(url) {this.previewType=url.substr(url.indexOf(".")+1);this.modalPreview=true;getWord({'url':url}).then(res => {let content = res;let blob = new Blob([content], { type: "application/pdf" });let reader = new FileReader();reader.readAsArrayBuffer(blob);reader.onload = function (e) {var arrayBuffer = e.target.result; //arrayBuffermammoth.convertToHtml({arrayBuffer:arrayBuffer}).then(displayResult).done();};function displayResult(result) {document.getElementById("wordView").innerHTML=result.value;}})},/********** 预览pdf ***************/previewPdf:function(url){this.previewType=url.substr(url.indexOf(".")+1);;getPdf({'url':url}).then(res => {const responseData = res;if (responseData != null) {let pdfUrl = window.URL.createObjectURL(new Blob([responseData], { type: "application/pdf" }));window.open(pdfUrl)}})},// 预览preview: function(url) {let suffixType=url.substr(url.indexOf('.')+1);console.log("后缀名称:"+suffixType);// excelif(suffixType==='xls'||suffixType==='xlsx'){this.previewExcel(url);}// wordelse if(suffixType==='docx'||suffixType==='doc'){this.previewWord(url);}// pdfelse if(suffixType==='pdf'){this.previewPdf(url);}},// 取消cancelPreview:function(){this.excelHtml='';this.wordHtml='';},
设置响应头(前后端都可以 ) :excel 和 word 的 Content-Type 为 arraybuffer,pdf的为 blob
后端
@ApiOperation("预览Excel")@SysLog("预览Excel")@PostMapping("/getExcel")public void getExcel(HttpServletResponse response,String url) throws IOException {response.setHeader("Content-Type", "arraybuffer");//我这里的 template是minio 你们能获取文件流就行了S3Object obj = template.getObject(url.substring(1, url.lastIndexOf("/")), url.substring(url.lastIndexOf("/") + 1));S3ObjectInputStream is = obj.getObjectContent();ServletOutputStream os = response.getOutputStream();byte[] buffer=new byte[1024];int len=0;while ((len=is.read(buffer))!=-1){os.write(buffer,0,len);}os.close();is.close();}
测试即可
错误
预览word文件时错误
Can‘t find end of central directory:is this a zip file?
1.你项目里面引用了mockjs文件,它的原理是重写了XMLHttpRequest,导致你上报插件找不到对应的方法;原理分析:mockjs是一个模拟后台接口的JS库,它的原理是重写了XMLHttpRequest,它可以在接口没出来时非常方便的模拟数据,上线之后不引用它即可。一般上报插件中会使用原生XMLHttpRequest,而原生XMLHttpRequest已被mockjs覆盖找不到相应的方法,所以会 出错。除了mockjs之外,zonejs、oboejs、fetchjs也有自己的的XMLHttpRequest库,请慎用。参考链接:/ZMJ_QQ/article/details/121264854
预览excel文件时出错
Error: Cannot read properties of undefined (reading ‘read‘) at FileReader.read
直接将import XLSX from 'xlsx'改为import * as XLSX from 'xlsx/xlsx.mjs'即可
到此就结束了 有不同意见的可以交流沟通哦!
参考链接: /canshegui2293/article/details/117373917