文件预览展示

  1. npm install xlsx --save

  2. npm install docx-preview --save

    <el-dialog
        title="文件预览"
        :visible.sync="dialogVisible"
        fullscreen
        append-to-body
        :before-close="handleClose"
        class="file-dialog">
        <div style="width: 100%;height: 100%;">
          <img v-if="imgUrl" :src="imgUrl" alt="" style="width: 100%;height: 100%">
          <!-- pdf和txt使用iframe -->
          <iframe v-if="pdfUrl" :src="pdfUrl" frameborder="0" style="width: 100%;height: 100%;min-height: 500px;"></iframe>
          <video v-if="videoUrl" :src="videoUrl" controls style="width: 100%;height: 100%;max-height: 800px;"></video>
          <div v-if="docFile">
            <div ref="file"></div>
          </div>
          <div v-if="xlsFile" class="excel-view-container">
            <!-- Excel使用tab选项卡来模拟表格里的sheet业 -->
            <el-tabs type="border-card" v-if="sheetNames && sheetNames.length" @tab-click="handleClick">
              <el-tab-pane :label="item" v-for="(item, index) in sheetNames" :key="index">
                <div class="excelView" v-html="excelView"></div>
              </el-tab-pane>
            </el-tabs>
          </div>
        </div>
      </el-dialog>
    
    
    <script>
      // 定义blob对应的type
      const fileTypeMap = {
        "xls": "application/vnd.ms-excel",
        "xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        "doc": "application/msword",
        "docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
        "pdf": "application/pdf",
        "ppt": "application/pdf",
        "pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
        "png": "image/png",
        "gif": "image/gif",
        "jpeg": "image/jpeg",
        "jpg": "image/jpeg",
        "txt": "text/plain",
      }
      export default {
        data() {
          return {
            imgUrl: '', //图片路径
            pdfUrl: '', //pdf路径
            videoUrl: '', //视频路径
            excelView: '', //表格转换后的html数据
            docFile: false, //是否是word文件
            xlsFile: false, //是否是Excel文件
            execlArraybufferData: null, //Excelblob转换为arraybuff数据
            sheetNames: null, //从数据中获取到的sheet页数组
            imgType: ['bmp', 'jpg', 'jpeg', 'png', 'tif', 'gif', 'pcx', 'tga', 'exif', 'fpx', 'svg', 'psd', 'cdr', 'pcd', 'dxf', 'ufo', 'eps', 'ai', 'raw', 'WMF', 'webp', 'avif', 'apng'],
          videoType: ['wmv', 'asf', 'asx', 'rm', 'rmvb', 'mp4', '3gp', 'mov', 'm4v', 'avi', 'dat', 'mkv', 'flv', 'vob'],
          wordType: ['text', 'pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'rar', 'zip', '7z', 'apz', 'ar', 'bz', 'car', 'dar', 'cpgz', 'f', 'ha', 'hbc', 'hbc2', 'hbe','hpk','hyp'],
          }
        },
        methods: {
          // 获取文件后缀
          getFileType(name) {
            if (name) {
              if (name.lastIndexOf(".") > -1) {
                return name.slice(name.lastIndexOf(".")+1);
              } else {
                return false
              }
            }
          },
          // 预览文件
          filePreviewPDF(path, name) {
            let fileType = this.getFileType(path), url, data
            // 后台接口方法url:接口地址,data给后台传的参数
            this.fileView(url, data).then(res => {
              let type = ''
              if (fileType) {
                type = fileTypeMap[fileType]
                if (this.imgType.includes(fileType)) {
                  // 图片类型的
                  const blob = new Blob([res], { type })
                  this.imgUrl = window.URL.createObjectURL(blob)
                } else if (this.videoType.includes(fileType)) {
                  // 视频类型的
                  const blob = new Blob([res])
                  this.videoUrl = window.URL.createObjectURL(blob)
                } else if (fileType === 'pdf' || fileType === 'txt') {
                  // pdf和文本类型的,用iframe打开
                  const blob = new Blob([res], { type })
                  this.pdfUrl = window.URL.createObjectURL(blob)
                } else if (fileType === 'doc' || fileType === 'docx') {
                  // word类型的用docx-preview插件
                  this.docFile = true
                  let docx = require("docx-preview")
                  this.$nextTick(() => {
                    docx.renderAsync(res, this.$refs.file).then(x => console.log("docx: finished",x))
                  })
                } else if (fileType === 'xls' || fileType === 'xlsx') {
                  // 表格类型的用xlsx插件
                  this.xlsFile = true
                  let XLSX = require("xlsx")
                  this.XLSX = XLSX
                  this.execlType = type
                  let blob = new Blob([res], {type: this.execlType})
                  let reader = new FileReader()
                  reader.readAsArrayBuffer(blob) // blob类型转换为ArrayBuffer类型
                  this.tabChange(0, reader)
                } else {
                  this.handleClose()
                  this.$modal.msgError('不支持此文件预览')
                }
              } else {
                this.handleClose()
                this.$modal.msgError('不支持此文件预览')
              }
            })
          },
          handleClick(data) {
            this.tabChange(data.index)
          },
          tabChange(index, reader) {
            this.excelView = ''
            let XLSX = this.XLSX
            let _this = this
    
            // 如果第一次进来
            if (!this.sheetNames) {
              // 文件转换加载完成后
              reader.onload = function() {
                let arraybufferData = this.result
                this.execlArraybufferData = arraybufferData
                let data = new Uint8Array(arraybufferData) // es2017的方法
                let workbook = XLSX.read(data, { type: "array" })  // 得到表格的array数据
                _this.workbooks = workbook  // 赋值到此组件最外面,一会要用
                let sheetNames = workbook.SheetNames; // 得到execl工作表名称集合,结果类似这样['sheet1','sheet2']
                _this.sheetNames = sheetNames  // 赋值到此组件最外面,一会要用
                let worksheet = workbook.Sheets[sheetNames[index]]  // 获取第几个工作表0就是'sheet1',以此类推
                _this['excelView'] = XLSX.utils.sheet_to_html(worksheet) // 把表格的array数据转换成html数据
                _this.$nextTick(function () {
                  // DOM加载完毕后执行,解决HTMLConnection有内容但是length为0问题。
                  _this.setStyle4ExcelHtml();
                })
              }
            } else {
              // 已经有数据了的时候直接获取对应sheet里的内容
              let worksheet = this.workbooks.Sheets[this.sheetNames[index]];
              this['excelView'] = XLSX.utils.sheet_to_html(worksheet)
            }
    
    
          },
          // 设置Excel转成HTML后的样式
          setStyle4ExcelHtml() {
            const excelViewDOM = document.getElementById("excelView");
            if (excelViewDOM) {
              const excelViewTDNodes = excelViewDOM.getElementsByTagName("td"); // 获取的是HTMLConnection
              if (excelViewTDNodes) {
                const excelViewTDArr = Array.prototype.slice.call(excelViewTDNodes);
                for (const i in excelViewTDArr) {
                  const id = excelViewTDArr[i].id; // 默认生成的id格式为sjs-A1、sjs-A2......
                  if (id) {
                    const idNum = id.replace(/[^0-9]/gi, ""); // 提取id中的数字,即行号
                    if (idNum && (idNum === "1" || idNum === 1)) {
                      // 第一行标题行
                      excelViewTDArr[i].classList.add("class4Title");
                    }
                    if (idNum && (idNum === "2" || idNum === 2)) {
                      // 第二行表头行
                      excelViewTDArr[i].classList.add("class4TableTh");
                    }
                  }
                }
              }
            }
          },
          handleClose() {
            this.$emit('closeDialog', false)
          }
        }
      }
    </script>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值