vue实现图片、pdf、xlsx、docx、mp4、txt在线预览功能

后端返回的是文件流形式,并且在浏览器输入链接是直接下载到本地的。
文件流遇到问题可参考这个
https://blog.csdn.net/Robergean/article/details/125981195

https://www.hangge.com/blog/cache/detail_3163.html
https://www.jb51.net/article/263468.htm
https://blog.csdn.net/Marion158/article/details/111672738?spm=1001.2101.3001.4242.1&utm_relevant_index=3
https://gitcode.net/mirrors/gosunadeod/vue-pdf.js-demo?utm_source=csdn_github_accelerator

image
image
image
image
image
image

pdf的要下载放在本地 看你放哪里引用地址记得改
链接: https://pan.baidu.com/s/11Z5WiImWthsIRUufcyWeUA?pwd=1234 
提取码: 1234 
https://gitcode.net/mirrors/gosunadeod/vue-pdf.js-demo?utm_source=csdn_github_accelerator
npm install video.js
npm i docx-preview --save
npm install luckyexcel
//luckysheet没有npm包 所以就需要引入在index.html
//引入index.html
  <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/plugins/css/pluginsCss.css' />
  <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/plugins/plugins.css' />
  <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/css/luckysheet.css' />
  <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/assets/iconfont/iconfont.css' />
  <script src="https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/plugins/js/plugin.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/luckysheet.umd.js"></script>

//传入数据
file:{
	name:'xxx',
	url:'.......'
}
<template>
    <el-dialog 
        :title="file.name" 
        :visible="visible" 
        width="80%" 
        :modal-append-to-body='false'
        :close-on-press-escape='false'
        :close-on-click-modal='false'
        :before-close="handleClose" 
        style="height:auto">
        <div v-if="imgShow">
            <img :src="downloadUrl" />
        </div>
        <div v-else-if="excelShow">
            <div id="luckysheet" style="margin:0px;padding:0px;width:100%;height:500px;"></div>
        </div>
        <div v-else-if="pdfShow">
        </div>
        <div v-else-if="txtShow">
            <span>{{txtPre}}</span>
        </div>
        <div v-else-if="docShow">
            <div id="preload_box"></div>
        </div>
        <div v-else-if="pptShow">
            <div id="pptx"></div>
        </div>
        <!--视频-->
        <div v-else-if="videoShow">
            <video preload="auto" :height="500" :width="width" align="center" controls="true">
                <source :src="downloadUrl" type="video/mp4" />
            </video>
        </div>
        <!--其他不能预览的-->
        <div v-else-if="otherShow"></div>
    </el-dialog>
</template>
<script>
import Video from 'video.js';
import 'video.js/dist/video-js.css';
import { renderAsync } from 'docx-preview';
import LuckyExcel from 'luckyexcel'
export default {
    props:{
        visible:{
            type:Boolean,
            default:false
        },
        file:{
            type:Object,
            default:()=>{}
        }
    },
    data(){
        return{
            fileName: '',
            downloadUrl: '',
            imgShow: false,
            pdfShow:false,
            pptShow:false,
            txtShow:false,
            docShow: false,
            excelShow: false,
            videoShow: false,
            //其他不能预览的
            otherShow: false,
            height: window.innerHeight + 'px',
            width: '100%',
            txtPre:''
        }
    },
    created(){
        this.fileName = this.file.name
        this.downloadUrl = this.file.url
        if (this.fileName.endsWith('png') || this.fileName.endsWith('jpg') || this.fileName.endsWith('jpeg')) {
        //图片
            this.downloadUrl = this.file.url
            this.imgShow = true;
        } else if (
            this.fileName.endsWith('docx')
        ) {
            this.wordFn()
            this.docShow = true;
        } else if (this.fileName.endsWith('xlsx')) {
            this.excelShow = true;//调用luckysheet
        } else if (this.fileName.endsWith('mp4') || this.fileName.endsWith('mp3')) {
            this.downloadUrl = this.file.url
            this.videoShow = true;
        } else if(this.fileName.endsWith('pdf')){
            后端接口().then(res=>{
                const blob = new Blob([res.data])
                var url = window.URL.createObjectURL(blob)
                if (process.env.NODE_ENV === "production"){//判断生产环境和开发环境对应不同的路径
                    window.open('/dist/common/static/pdf/web/viewer.html?file=' + encodeURIComponent(url))
                }else{
                    window.open('/static/pdf/web/viewer.html?file=' + encodeURIComponent(url))
                }
                this.$emit('close')
            })//调用pdf查看器
            this.handleClose()
        }else if (this.fileName.endsWith('txt')){
            后端接口().then(res=>{
                let blob = new Blob([res.data]);
                blob.text().then(data =>{
                    // data:指成功读取到的内容
                    this.txtPre = data
                }).catch(err=>{
                    //err: 指读取失败后返回的错误内容
                })
            })
            this.txtShow = true
        } else {
            this.$message.error('该文件不支持在线预览!')
            this.handleClose()
        }
    },
    mounted(){
        if(this.excelShow){
            后端接口().then(res=>{
                let blob = new Blob([res.data]);
                let file = new File([blob],this.fileName,{ type: 'excel/xlsx' });
                console.log("file",file)
                LuckyExcel.transformExcelToLucky(
                    file,
                    function (exportJson,luckysheetfile) {
                        // 获得转化后的表格数据后,使用luckysheet初始化,或者更新已有的luckysheet工作簿
                        // 注:luckysheet需要引入依赖包和初始化表格容器才可以使用
                        luckysheet.create({
                            container: 'luckysheet', //luckysheet is the container id
                            showinfobar: false,
                            lang: 'zh', // 设定表格语言
                            allowEdit: false,//作用:是否允许前台编辑
                            // allowUpdate: true,
                            sheetFormulaBar: false,
                            allowCopy: true, //是否允许拷贝
                            showtoolbar: false, //是否第二列显示工具栏
                            showinfobar: false, //是否显示顶部名称栏
                            showsheetbar: true, //是否显示底部表格名称区域
                            showstatisticBar: true, //是否显示底部计数栏
                            pointEdit: false, //是否是编辑器插入表格模式
                            pointEditUpdate: null, //编辑器表格更新函数
                            data: exportJson.sheets,
                            title: exportJson.info.name,
                            userInfo: exportJson.info.name.creator,
                        });
                    },
                    function (err) {
                        logger.error('Import failed. Is your fail a valid xlsx?');
                    }
                );
                let formData = new FormData();
                formData.append('file',file);
            })
        }
    },
    methods:{
        async wordFn(){
            let res = await 后端接口()
            console.log(res.data)
            renderAsync(res.data, document.getElementById("preload_box"), null, {
                className: "docx", // 默认和文档样式类的类名/前缀
                inWrapper: true, // 启用围绕文档内容渲染包装器
                ignoreWidth: false, // 禁止页面渲染宽度
                ignoreHeight: false, // 禁止页面渲染高度
                ignoreFonts: false, // 禁止字体渲染
                breakPages: true, // 在分页符上启用分页
                ignoreLastRenderedPageBreak: true, //禁用lastRenderedPageBreak元素的分页
                experimental: false, //启用实验性功能(制表符停止计算)
                trimXmlDeclaration: true, //如果为真,xml声明将在解析之前从xml文档中删除
                debug: false, // 启用额外的日志记录
            })
        },
        handleClose(){
            this.$emit('update:visible',false)
        },
    }
}
</script>
posted @ 2022-11-08 11:43  Chaplink  阅读(2084)  评论(0编辑  收藏  举报