最近公司项目中要实现 文档上传之后要在线预览 :当时心想这不是挺简单的吗 嘿嘿!直接用在线的 XDOC 就能实现!
后来说客户那边是内网…………哎
外网预览
访问网址:http://www.xdocin.com/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; //arrayBuffer
mammoth.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);
// excel
if(suffixType==='xls'||suffixType==='xlsx'){
this.previewExcel(url);
}
// word
else if(suffixType==='docx'||suffixType==='doc'){
this.previewWord(url);
}
// pdf
else 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库,请慎用。
参考链接:https://blog.csdn.net/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'即可
到此就结束了 有不同意见的可以交流沟通哦!
参考链接: https://blog.csdn.net/canshegui2293/article/details/117373917