记录一次VUE移动端H5的文件预览

2,778 阅读2分钟

在移动端直接预览上传的文件,一开始考虑成型的线上文件预览服务如xdoc,但是考虑到纯线上服务我们设计报销审批的敏感文件信息,自己部署服务需要付费,所以另辟蹊径,单独对各个文件类型进行预览处理

参考问答: segmentfault.com/q/101000002…

segmentfault.com/q/101000002…

一、图片预览

第一种方式

参考了blog.csdn.net/qq_39258914… 并使用了文件中提及的w-previewimg图片预览组件(暂时采用这个预览单个图片)

安装

npm install -s w-previewimg 引入

import wimg from "w-previewimg"; //图片预览插件 使用,current即当前需要看的图片

<wimg
  :show="showBigImg"
  :imgs="thumbsList"
  :currentImg="current"
  @close="showBigImg=false"
  class="wimg"
></wimg>

点击可关闭预览(移动端够用了,图片预览比较简单哈哈,可以用其他插件实现也)

第二种

转成base64链接

`data:image/jpg;base64,` + btoa(new Uint8Array(res).reduce((data,key) => {data + String.fromCharCode(key),''}))

二、pdf预览

pdf预览使用vue-pdf插件

github地址:github.com/FranckFreib…

参考其中的demo实现,组件代码如下,可以在用到的地方按需引用,我在最后的图片预览组件中会提供,我们涉及的预览比较简单(单页pdf预览)有需要的可以自己看一下github中的demo做深层次的实现

<template>
  <div class="excel-container">
    <pdf ref="pdf" :src="url"></pdf>
  </div>
</template>
 
<style sceped lang="scss">
.excel-container {
  width: 100%;
}
</style>
 
<script>
import pdf from "vue-pdf"; //pdf预览插件
export default {
  name: "pdfPreview",
  props: {
    url: {
      type: String,
      required: true
    }
  },
  components: { pdf },
  data() {
    return {
      data: []
    };
  },
  watch: {
    url(val) {
      console.log(val, "val");
      this.previewFile();
    }
  },
  methods: {
    previewFile() {
      var self = this;
      try {
        this.pdfUrl = this.url;
        let loadingTask = pdf.createLoadingTask(url);
      } catch (e) {
        console.log(e);
        this.$vux.loading.hide();
        this.$emit("errorPreview");
      }
    }
  }
};
</script>

三、excel文件预览

感谢前面中问答给出的提示,在本vue项目中采用了sheet.js插件进行excel转为html然后在页面上渲染出来(美观度一般,我调试的不到位)

github地址:github.com/SheetJS/she…,,我们用到的在这里

照葫芦画瓢,预览excel组件源码如下

<template>
  <div class="excel-container">
    <div ref="preview"></div>
  </div>
</template>
 
<style sceped lang="scss">
.excel-container {
  width: 100%;
}
</style>
 
<script>
import XLSX from "xlsx";
export default {
  name: "excelPreview",
  props: {
    url: {
      type: String,
      required: true
    }
  },
  data() {
    return {
      data: []
    };
  },
  watch: {
    url(val) {
      console.log(val, "val");
      this.previewFile();
    }
  },
  methods: {
    previewFile() {
      var self = this;
      try {
        var req = new XMLHttpRequest();
        req.open("GET", this.url, true);
        req.responseType = "arraybuffer";
        req.onload = e => {
          console.log(req.response, "req.response");
          var binary = "";
          var bytes = new Uint8Array(req.response);
          var length = bytes.byteLength;
          for (var i = 0; i < length; i++) {
            binary += String.fromCharCode(bytes[i]);
          }
          var wb = XLSX.read(binary, { type: "binary" });
          var wsname = wb.SheetNames[0];
          var ws = wb.Sheets[wsname];
          var HTML = XLSX.utils.sheet_to_html(ws);
          if (this.$refs.preview) {
            this.$refs.preview.innerHTML = HTML;
          }
        };
 
        req.send();
      } catch (e) {
        console.log(e);
        this.$emit("errorPreview");
      }
    }
  }
};
</script>

预览效果(我这个有点丑,功能实现了哈,我上传的FocusT25的课表,信息也比较多,有余力的自己调整一下)

注:

XLSX可以使用sheet_to_json进行转换,HTML可以使用v-html放在dom结构上

var work = XLSX.read(response, {type: 'binary'})
              console.log(111==="",work)
              // let sheet = work.SheetNames[0]
              let sheet = work.SheetNames
              console.log(sheet)
              try {
                // 获取当前工作表的数据
                let htmlData
                for (var i = 0; i < sheet.length; i++) {
                  const workSheet = work.Sheets[sheet[i]]
                  console.log(workSheet,'workSheet')
                  if (i == 0) {
                    htmlData = `<div>${sheet[i]}</div>`
                  } else {
                    htmlData += `<div>${sheet[i]}</div>`
                  }
                  htmlData += XLSX.utils.sheet_to_html(workSheet,{header:'',footer:''})
                  // console.log(htmlData)
                }
                // // 转换为数据   1.json数据有些问题  2.html样式需要修改
                // const sheet2JSONOpts = { defval: '' }
                // let jsonData = XLSX.utils.sheet_to_json(workSheet,sheet2JSONOpts)
                htmlData = htmlData === '' ? htmlData : htmlData.replace(/<table/g, `<table class="tableFormApprove" border="1px solid #ccc" cellpadding="0" cellspacing="0"`)
                htmlData = htmlData === '' ? htmlData : htmlData.replace(/<tr/g,`<tr style="background:#F5F7FA"`)
                this.sheetActive = htmlData
              } catch (error) {
                this.sheetActive = `<h1 style='text-align: center;'>无内容</h1>`
              }

四、word预览

word预览使用mammoth.js进行转换和显示

github地址:github.com/mwilliamson…  可以参考学习!画个重点,我用的是这部分

如是先get请求获取文件buffer然后再进行转换

关键部分代码


    previewFile() {
      let _this=this;
      try {
        var xhr = new XMLHttpRequest();
        xhr.open("GET", this.url);
        xhr.responseType = "arraybuffer";
        let self = this;
 
        xhr.onload = function(e) {
          var arrayBuffer = xhr.response; //arrayBuffer
 
          mammoth
            .convertToHtml({ arrayBuffer: arrayBuffer })
            .then(displayResult)
            .done();
 
          function displayResult(result) {
            console.log(result);
            self.$refs.docPreview.innerHTML = result.value || "";
          }
        };
        xhr.send();
      } catch (e) {
        console.log(e);
        _this.$emit("errorPreview");
      }
    }

我将这几个组件的应用封装在了图片预览组件当中,用模态窗口做了承接,做了简单的文件类型的判断,根据不同的业务需求也可以在应用时做不同的处理

原文链接:blog.csdn.net/u012439689/…