实现预览Excel PDF Word 文件 (外网,内网)

最近公司项目中要实现 文档上传之后要在线预览 :当时心想这不是挺简单的吗 嘿嘿!直接用在线的 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

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值