首页 > 其他分享 >vue js 预览word, Excel, TXT,PDF 图片等。

vue js 预览word, Excel, TXT,PDF 图片等。

时间:2023-02-16 14:13:51浏览次数:48  
标签:XLSX docx vue word fileType Excel let const data

npm 安装插件

npm install xlsx --save
npm install docx-preview --save

  npm install axios

 

template 部分 //这里封装成一个组件

<template>
  <div class="">
    <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: 100vh"
      ></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>
  </div>
</template>
<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 {
  props: ["previewType", "previewUrl"],
  data() {
    return {
      fileType: "", //文件类型
      data: "", //文件路径,blob 类型

      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",
      ],
    };
  },
  watch: {
    previewType: {
      handler(value) {
        this.fileType = value;
      },
      immediate: true, // 重点
      deep: true, // 重点
    },

    previewUrl: {
      handler(value) {
        this.data = value;
      },
      immediate: true, // 重点
      deep: true, // 重点
    },
  },
  mounted() {
    this.filePreviewPDF();
  },
  methods: {
    // 预览文件
    filePreviewPDF() {
      if (this.imgType.includes(this.fileType)) {
        // 图片类型的
        this.imgUrl = window.URL.createObjectURL(this.data);
      } else if (this.videoType.includes(this.fileType)) {
        // 视频类型的
        this.videoUrl = window.URL.createObjectURL(this.data);
      } else if (this.fileType == "pdf" || this.fileType == "txt") {
        // pdf和文本类型的,用iframe打开
        this.pdfUrl = window.URL.createObjectURL(this.data);
        console.log(this.pdfUrl);
      } else if (this.fileType == "doc" || this.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 (this.fileType == "xls" || this.fileType == "xlsx") {
        // 表格类型的用xlsx插件
        this.xlsFile = true;
        let XLSX = require("xlsx");
        this.XLSX = XLSX;
        this.execlType = type;
        let reader = new FileReader();
        reader.readAsArrayBuffer(this.data); // blob类型转换为ArrayBuffer类型
        this.tabChange(0, reader);
      } else {
        this.handleClose();
        this.$message.error("不支持此文件预览");
      }
    },
    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>

 

tempate部分这里是应用的地方

<!-- 预览附件 -->
    <el-dialog title="预览附件" :visible.sync="previewAnnex" width="50%" :close-on-click-modal="false" :close-on-press-escape="false" :destroy-on-close="true">
      
      <!-- <iframe :src="previewUrl" frameborder="0" style=" z-index: 1000;height: 800px;width: 100%" ></iframe> -->

      <previewFile :previewUrl="previewUrl" :previewType="previewType" />

      <div slot="footer" class="batch-dialog-footer">
        <el-button type="primary" @click="previewAnnex = false">关闭</el-button>
      </div>
    </el-dialog>

data部分

//预览附件
      previewAnnex: false,
      previewUrl: "",
      previewType: "",

script部分

import axios from "axios";

method 方法部分,获取地址部分

getName(path).then((res) => { //这里是获取后端返回的 uuid 或者是路径部分
        this.coverUrl(res.data.fileName, path);
      });
//文件预览判断
    coverUrl(row, path) {
      var type = this.iconByType(row);

      axios({ //需要把地址转换成 blob 格式
        method: "get",
        url: path, //这里的地址是你可以访问到的地址。 例如:代理 + 接口 + uuid = 可以访问到已经上传到后端的地址
        responseType: "blob",
      }).then((res) => {
        this.previewUrl = res.data;
        this.previewType = type;
        this.previewAnnex = true;
      });
    },
//获取文件后缀名
    iconByType(filename) {
      return filename.substring(filename.lastIndexOf(".") + 1, filename.length);
    },

 

标签:XLSX,docx,vue,word,fileType,Excel,let,const,data
From: https://www.cnblogs.com/majiayin/p/17126447.html

相关文章