在线附件预览

###word,excel,pdf,text,img预览

第一步:写一个button

<el-button
    class="openWindown-btn"
    link
    type="primary"
    @click="openWindown(scope.row)"
>预览
</el-button>

 第二步:实现跳转方法

/**
 * =================文件预览,下载====================
 */
const openWindown = (row: any) => {
  window.open(`/filePreview?id=${row.id}&fileName=${row.name}`, "_blank");
};

第三步:写组件

注意点:lucksheet需要再index.html中引入依赖

<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet/dist/plugins/css/pluginsCss.css' />
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet/dist/plugins/plugins.css' />
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet/dist/css/luckysheet.css' />
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet/dist/assets/iconfont/iconfont.css' />
<script src="https://cdn.jsdelivr.net/npm/luckysheet/dist/plugins/js/plugin.js"></script>
<script src="https://cdn.jsdelivr.net/npm/luckysheet/dist/luckysheet.umd.js"></script>
<template>
  <div v-loading="loading" class="out-box">
    <div class="img-box" v-if="state.type == 'JPG' ||
      state.type == 'jpg' ||
      state.type == 'JPEG' ||
      state.type == 'jpeg' ||
      state.type == 'PNG' ||
      state.type == 'png'
      ">
      <img :src="state.imgUrl" alt="" />
    </div>
    <div v-else-if="state.type == 'docx'" :style="{ height: getHeight }">
      <div ref="docx" class="docx-box"></div>
    </div>
    <div v-else-if="state.type == 'xlsx'">
      <div id="luckysheet"></div>
    </div>
    <!-- <div v-else-if="state.type == 'txt'" :style="{ height: getHeight }">
      <div ref="txt" id="txt-box"></div>
    </div> -->
    <div v-else-if="state.type == 'pdf'" class="pdf-box" :style="{ height: getHeight }">
      <vue-pdf-embed style="padding: 2rem 0; box-shadow: 1px 0px 15px #3a3737" :source="state.pdfSource" />
    </div>
    <div v-else class="notType">
      <p>当前文件不支持预览,请下载查看</p>
      <p>
        支持预览类型:"JPG", "JPEG", "PNG", "jpg", "jpeg", "png", "pdf", "xlsx",
        "docx"
      </p>
    </div>
  </div>
</template>
<script setup lang="ts" name="filePreview">
import { ref, reactive, nextTick, onMounted, computed } from "vue";
import { useRoute } from "vue-router";
const route = useRoute();
import { ElMessage } from "element-plus";
import { commonService } from "/@/api/common";
import { renderAsync } from "docx-preview";
import LuckyExcel from "luckyexcel";
import VuePdfEmbed from "vue-pdf-embed";//
import router from "/@/router";

const loading = ref(false);

const docx = ref();
const txt = ref();

const state = reactive<any>({
  fileName: route.query.fileName,
  type: "",
  id: route.query.id,
  imgUrl: "",
  pdfSource: "",
});
state.type = state.fileName.substr(state.fileName?.lastIndexOf(".") + 1);
const getHeight = computed(() => {
  return window.innerHeight + "px";
});
function init(fileName: string, type: string, id: any) {
  console.log("type:::::", type);
  let arr = ["JPG", "JPEG", "PNG", "jpg", "jpeg", "png", "pdf", "xlsx", "docx"];
  if (!arr.includes(type)) {
    // ElMessage({
    //   type: "warning",
    //   message: "当前文件不支持预览,请下载查看!",
    // });
    return;
  }
  loading.value = true;
  if (
    type == "JPG" ||
    type == "JPEG" ||
    type == "PNG" ||
    type == "png" ||
    type == "jpg" ||
    type == "jpeg"
  ) {
    commonService
      .preView_IMG(id)
      .then((res: any) => {
        if (res) {
          let blob = new Blob([res.data], { type: res.data.type });
          const imageUrl = URL.createObjectURL(blob);
          state.imgUrl = imageUrl;
          loading.value = false;
          //   (srcList.value = [imageUrl]), (loading.value = true);
        } else {
          ElMessage({
            type: "error",
            message: "接口请求失败",
          });
          loading.value = false;
        }
      })
      .catch(function (error) {
        loading.value = false;
      });
  } else if (type == "docx") {
    commonService
      .preView_Word(id)
      .then((res: any) => {
        let docxOptions = {
          className: `${type}box`, // string:默认和文档样式类的类名/前缀
          inWrapper: true, // boolean:启用围绕文档内容的包装器渲染
          ignoreWidth: false, // boolean:禁用页面的渲染宽度
          ignoreHeight: false, // boolean:禁止渲染页面高度
          ignoreFonts: false, // boolean:禁用字体渲染
          breakPages: true, // boolean:在分页符上启用分页
          ignoreLastRenderedPageBreak: true, // boolean:在 lastRenderedPageBreak 元素上禁用分页
          experimental: false, // boolean:启用实验功能(制表符停止计算)
          trimXmlDeclaration: true, // boolean:如果为true,解析前会从​​ xmlTemplate 文档中移除 xmlTemplate 声明
          useBase64URL: false, // boolean:如果为true,图片、字体等会转为base 64 URL,否则使用URL.createObjectURL
          useMathMLPolyfill: false, // boolean:包括用于 chrome、edge 等的 MathML polyfill。
          showChanges: false, // boolean:启用文档更改的实验性渲染(插入/删除)
          debug: false, // boolean:启用额外的日志记录
        };
        if (res) {
          let docData = new Blob([res.data], { type: res.data.type });
          renderAsync(docData, docx.value, undefined, docxOptions).then(
            (x) => { }
          );
          loading.value = false;
        } else {
          ElMessage({
            type: "error",
            message: "接口请求失败",
          });
          loading.value = false;
        }
      })
      .catch(function (error) {
        loading.value = false;
      });
  } else if (type == "pdf") {
    commonService
      .preView_PDF(id)
      .then((res: any) => {
        if (res) {
          let blob = new Blob([res.data], { type: "application/pdf;charset=utf-8" });
          let fileURL = URL.createObjectURL(blob);
          window.open(fileURL, "_self");
          loading.value = false;
        } else {
          ElMessage({
            type: "error",
            message: "接口请求失败",
          });
          loading.value = false;
        }
      })
      .catch(function (error) {
        loading.value = false;
      });
  } else if (type == "xlsx") {
    //表格
    commonService
      .preView_Excel(id)
      .then((res: any) => {
        if (res) {
          const blob = new Blob([res.data], {
            type: res.data.type,
          });
          var file1 = new File([blob], fileName, {
            type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
            lastModified: Date.now(),
          });
          loadExcel(file1);
          loading.value = false;
        } else {
          ElMessage({
            type: "error",
            message: "接口请求失败",
          });
          loading.value = false;
        }
      })
      .catch(function (error) {
        loading.value = false;
      });
  } else if (type == "txt") {
    console.log(type, id, fileName);
    // var reader = new FileReader;
    // reader.readAsText(file, 'gb2312');
    commonService.preView_Txt(id).then((res: any) => {
      console.log(res);
      
      let txtData = new Blob([res.data], { type: res.data.type });
      // renderAsync(docData, docx.value, undefined, docxOptions).then(
      //   (x) => { }
      // );
      // loading.value = false;

      // let reader = new FileReader;
      // reader.readAsText(file, 'gb2312');
      // renderAsync(docData, docx.value, undefined, docxOptions)
      // reader.onload = (evt: any) => {
      //   var data = evt.target.result;
      //   // $('#textarea_id').val(data);
      // }
    })
      .finally(() => {
        loading.value = false;
      });
  }
}
/**
 * ========================excel======================
 */
// 配置项
const options = {
  container: "luckysheet", // 设定DOM容器的id
  title: "luckysheet", // 设定表格名称
  lang: "zh", // 设定表格语言
  data: [
    {
      name: "Sheet1",
    },
  ],
};
const initLuckysheet = () => {
  luckysheet.destroy();
  luckysheet.create(options);
};
nextTick(() => {
  // 初始化表格
  initLuckysheet();
});
const jsonData = ref({});
// 加载excel
const loadExcel = (evt: any) => {
  console.log("evt::::", evt);

  const files = evt;
  if (files == null || files.length == 0) {
    return;
  }
  let name = files.name;
  let suffixArr = name.split("."),
    suffix = suffixArr[suffixArr.length - 1];
  if (suffix != "xlsx") {
    throw new Error("当前仅支持xlsx文件");
  }
  LuckyExcel.transformExcelToLucky(
    files,
    function (exportJson: any, luckysheetfile: any) {
      if (exportJson.sheets == null || exportJson.sheets.length == 0) {
        return;
      }
      jsonData.value = exportJson;
      // luckysheet.destroy();
      let option = {
        container: "luckysheet", //luckysheet is the container id
        data: exportJson.sheets,
        config: {},
        lang: "zh", // 设定表格语言
        title: exportJson.info.name,
        userInfo: exportJson.info.name.creator,
        showtoolbar: false, // 是否显示工具栏
        showinfobar: false, // 是否显示顶部信息栏
        showsheetbar: true,
        showstatisticBar: false, // 是否显示底部sheet按钮
        cellRightClickConfig: {
          copy: false, // 复制
          copyAs: false, // 复制为
          paste: false, // 粘贴
          insertRow: false, // 插入行
          insertColumn: false, // 插入列
          deleteRow: false, // 删除选中行
          deleteColumn: false, // 删除选中列
          deleteCell: false, // 删除单元格
          hideRow: false, // 隐藏选中行和显示选中行
          hideColumn: false, // 隐藏选中列和显示选中列
          rowHeight: false, // 行高
          columnWidth: false, // 列宽
          clear: false, // 清除内容
          matrix: false, // 矩阵操作选区
          sort: false, // 排序选区
          filter: false, // 筛选选区
          chart: false, // 图表生成
          image: false, // 插入图片
          link: false, // 插入链接
          data: false, // 数据验证
          cellFormat: false, // 设置单元格格式,
        },
        enableAddRow: false, // 允许添加行
        enableAddBackTop: false, // 允许回顶部
        sheetFormulaBar: false, // 是否显示公式栏
        showstatisticBarConfig: {
          zoom: true,
        },
      };
      window.luckysheet.create(option);
      // window.luckysheet
    }
  );
};
onMounted(() => {
  init(state.fileName, state.type, state.id);
});

nextTick(() => { });
</script>
<style lang="scss" scoped>
.out-box {
  height: 100%;
  background: #808080;

  .img-box {
    padding: 1rem;
    max-height: 100%; /* 大高度 */
    max-width: 100%;
    overflow: auto; /* 滚动条 */

    img {
      width: 50%;
      margin: 0 auto;
      display: block;
      box-shadow: 1px 0px 15px #3a3737;
    }
  }

  .docx-box {
    height: 100%;
    overflow: scroll;
  }

  .pdf-box {
    width: 50%;
    margin: 0rem auto;
    overflow: scroll;
  }

  #luckysheet {
    margin: 0px;
    padding: 0px;
    position: absolute;
    width: 100%;
    height: 100%;
    left: 0px;
    top: 0px;
    bottom: 0px;
  }

  .notType {
    position: fixed;
    top: -30%;
    left: 0;
    right: 0;
    bottom: 0;
    height: 100px;
    margin: auto;
    border-radius: 10px;
    width: 800px;
    padding: 10px;
    background: rgba(255, 255, 255, 0.8);
    box-sizing: border-box;

    p {
      text-align: center;
      line-height: 2rem;
      font-size: 18px;
    }

    p:first-child {
      font-size: 22px;
      color: rgb(220, 26, 26);
      line-height: 3rem;
    }
  }
}
</style>

pdf可以不使用插件浏览器可以直接解析pdf,excel这里下载的插件是 LuckyExcel这个插件,docx使用的docx-preview这个插件

接口类型: 

/**
   * 文件预览excel
   */
  static async preView_Excel(data: number): Promise<MyAxiosResponse> {
    return request({
      url: `/annexes/getByteStream/${data}`,
      method: "post",
      responseType: "arraybuffer", //告诉服务器想到的响应格式
      headers: {
        "Content-Type":
          "application/vnd.ms-excel;application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
      },
    });
  }
  //文件预览pdf
  static async preView_PDF(data: number): Promise<MyAxiosResponse> {
    return request({
      url: `/annexes/getByteStream/${data}`,
      method: "POST",
      responseType: "blob",
      headers: {
        "Content-Type": "application/pdf;charset=UTF-8",
      },
    });
  }
  //文件预览img
  static async preView_IMG(data: number): Promise<MyAxiosResponse> {
    return request({
      url: `/annexes/getByteStream/${data}`,
      method: "POST",
      responseType: "blob",
      headers: {
        Accept: "application/octet-stream",
      },
    });
  }
  //文件预览Word
  static async preView_Word(data: number): Promise<MyAxiosResponse> {
    return request({
      url: `/annexes/getByteStream/${data}`,
      method: "POST",
      responseType: "blob",
      // headers: {
      //   "Content-Type":
      //     "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
      // },
    });
  }
  //TXT预览
  static async preView_Txt(data: number): Promise<MyAxiosResponse> {
    return request({
      url: `/annexes/getByteStream/${data}`,
      method: "POST",
      responseType: "blob",
      // headers: {
      //   "Content-Type":
      //     "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
      // },
    });
  }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值