如果项目是外网,iframe + 微软提供的免费在线预览office接口 https://view.officeapps.live.com/op/view.aspx?src=http://static.shanhuxueyuan.com/test6.docx 实现以上类型文件的预览(还有doc/ppt)等

如果项目是内网,没做内网穿透,那就只能装插件

xls/xlsx/docx

用的 vue-office,安装使用看官网介绍,非常详细简洁,但是注意xls加载不了excel样式

1.xls
在这里插入图片描述
2.xlsx
在这里插入图片描述

3.docx
在这里插入图片描述

pdf/txt

vue-office也有pdf插件@vue-office/pdf,不过我用了iframe实现,因为浏览器自带的PDF功能挺丰富,还能加载.txt文件iframe加载pdf

pptx

使用PPTXjs实现
在这里插入图片描述

  1. 点此下载 PPTXjs压缩包,解压后放在public目录下

在这里插入图片描述

  1. 在index.html中引入css/js

css

<link rel="stylesheet" href="/PPTXjs/css/pptxjs.css">
<link rel="stylesheet" href="/PPTXjs/css/nv.d3.min.css"> <!-- for charts graphs -->

js

<script type="text/javascript" src="/PPTXjs/js/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="/PPTXjs/js/jszip.min.js"></script> <!-- v2.. , NOT v.3.. -->
<script type="text/javascript" src="/PPTXjs/js/filereader.js"></script> <!--https://github.com/meshesha/filereader.js -->
<script type="text/javascript" src="/PPTXjs/js/d3.min.js"></script> <!-- for charts graphs -->
<script type="text/javascript" src="/PPTXjs/js/nv.d3.min.js"></script> <!-- for charts graphs -->
<script type="text/javascript" src="/PPTXjs/js/pptxjs.js"></script>
<script type="text/javascript" src="/PPTXjs/js/divs2slides.js"></script> <!-- for slide show -->
  1. iframe获取动态文件地址

在PPTXjs/index.html页面,获取传给iframe的动态文件地址

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/3a60d648f553423ea7f0f11a370d156b.png

代码

<template>
  <el-dialog
    v-loading="loading"
    :title="dialogTitle"
    fullscreen
    lock-scroll
    center
    ref="dialog"
    custom-class="dialog"
    :close-on-press-escape="false"
    :visible.sync="dialogVisible"
    :before-close="handleClose"
  >
    <!-- <vue-office-pdf
      v-if="['pdf'].includes(fileType)"
      :src="fileUrl"
       :style="{ height: bodyHeight + 'px' }"
      @rendered="renderedHandler('pdf')"
      @error="errorHandler('pdf')"
    /> -->
    <vue-office-docx
      v-if="['doc', 'docx'].includes(fileType)"
      :src="fileUrl"
      :style="{ height: bodyHeight + 'px' }"
      @rendered="renderedHandler('doc')"
      @error="errorHandler('doc')"
    />
    <vue-office-excel
      v-else-if="['xls', 'xlsx'].includes(fileType)"
      :src="fileUrl"
      :options="excelOptions"
      :style="{ height: bodyHeight + 'px' }"
      @rendered="renderedHandler('xls')"
      @error="errorHandler('xls')"
    />
    <iframe
      v-else-if="['pdf', 'txt', 'pptx'].includes(fileType)"
      id="iframe"
      :src="
        ['pdf', 'txt'].includes(fileType)
          ? fileUrl
          : `/PPTXjs-master/index.html?file=` + fileUrl
      "
      :style="{ height: bodyHeight + 'px' }"
    ></iframe>
    <div slot="footer">
      <el-button type="primary" round @click="handleClose">关闭</el-button>
    </div>
  </el-dialog>
</template>

<script>
//引入VueOfficeDocx组件
import VueOfficeDocx from "@vue-office/docx";
//引入相关样式
import "@vue-office/docx/lib/index.css";
//引入VueOfficeExcel组件;
import VueOfficeExcel from "@vue-office/excel";
//引入相关样式
import "@vue-office/excel/lib/index.css";
//引入VueOfficePdf组件
// import VueOfficePdf from "@vue-office/pdf";
export default {
  components: {
    VueOfficeDocx,
    VueOfficeExcel,
    // VueOfficePdf,
  },
  data() {
    return {
      dialogVisible: false,
      dialogTitle: "",
      loading: false,
      frontUrl: process.env.VUE_APP_BASE_API + "/file/preOrDown?filePath=",
      behindtUrl: "&type=0",
      // excel: "http://static.shanhuxueyuan.com/demo/excel.xlsx", //设置文档地址
      // pdf: "http://static.shanhuxueyuan.com/test.pdf", //设置文档地址
      // docx: "http://static.shanhuxueyuan.com/test6.docx", //设置文档网络地址,可以是相对地址
      // https://www.hengdianworld.com/DownloadFile/%E6%A8%AA%E5%BA%97%E5%BD%B1%E8%A7%86%E5%9F%8E%E6%B8%B8%E8%A7%88%E6%89%8B%E5%86%8C.docx
      docOptions: {
        className: "docx", //class name/prefix for default and document style classes
        inWrapper: true, //enables rendering of wrapper around document content
        ignoreWidth: false, //disables rendering width of page
        ignoreHeight: false, //disables rendering height of page
        ignoreFonts: false, //disables fonts rendering
        breakPages: true, //enables page breaking on page breaks
        ignoreLastRenderedPageBreak: false, //disables page breaking on lastRenderedPageBreak elements
        experimental: false, //enables experimental features (tab stops calculation)
        trimXmlDeclaration: true, //if true, xml declaration will be removed from xml documents before parsing
        useBase64URL: false, //if true, images, fonts, etc. will be converted to base 64 URL, otherwise URL.createObjectURL is used
        useMathMLPolyfill: false, //includes MathML polyfills for chrome, edge, etc.
        showChanges: false, //enables experimental rendering of document changes (inserions/deletions)
        debug: false, //enables additional logging
      },
      excelOptions: {
        xls: true, //预览xlsx文件设为false;预览xls文件设为true
        // minColLength: 0, // excel最少渲染多少列,如果想实现xlsx文件内容有几列,就渲染几列,可以将此值设置为0.
        // minRowLength: 0, // excel最少渲染多少行,如果想实现根据xlsx实际函数渲染,可以将此值设置为0.
        // widthOffset: 10, //如果渲染出来的结果感觉单元格宽度不够,可以在默认渲染的列表宽度上再加 Npx宽
        // heightOffset: 10, //在默认渲染的列表高度上再加 Npx高
        beforeTransformData: (workbookData) => {
          return workbookData;
        }, //底层通过exceljs获取excel文件内容,通过该钩子函数,可以对获取的excel文件内容进行修改,比如某个单元格的数据显示不正确,可以在此自行修改每个单元格的value值。
        transformData: (workbookData) => {
          return workbookData;
        }, //将获取到的excel数据进行处理之后且渲染到页面之前,可通过transformData对即将渲染的数据及样式进行修改,此时每个单元格的text值就是即将渲染到页面上的内容
      },
      fileUrl: "",
      fileType: "",
      bodyHeight: "",
    };
  },
  methods: {
    init(row) {
      this.loading = true;
      this.dialogVisible = true;
      this.dialogTitle = row.originalTitle;
      this.fileUrl = this.frontUrl + row.filePath + this.behindtUrl;
      this.fileType = row.filePath.split(".")[1];
      console.log("fileType", this.fileType);
      console.log("fileUrl", this.fileUrl);
      this.excelOptions.xls = this.fileType == "xls" ? true : false;
      this.$nextTick(() => {
        const dialog = document.getElementsByClassName("dialog")[0];
        const dialogChildren = dialog.children;
        const headerHeight = dialogChildren[0].offsetHeight;
        const footerHeight = dialogChildren[2].offsetHeight;
        this.bodyHeight = dialog.offsetHeight - headerHeight - footerHeight;

        if (["pdf", "txt", "pptx"].includes(this.fileType)) {
          const iframe = document.getElementById("iframe");
          // attachEvent为IE专用方法
          if (iframe.attachEvent) {
            iframe.attachEvent("onload", function () {
              console.log("iframe is now loaded.");
              this.loading = false;
            });
          } else {
            iframe.onload = () => {
              console.log("iframe is now loaded.");
              this.loading = false;
            };
          }
        }
      });
    },
    renderedHandler(type) {
      console.log("渲染完成", type);
      this.loading = false;
    },
    errorHandler(type) {
      console.log("渲染失败", type);
      this.loading = false;
    },
    handleClose() {
      this.dialogVisible = false;
      this.dialogTitle = "";
      this.fileUrl = "";
      this.fileType = "";
      this.bodyHeight = "";
    },
  },
};
</script>
<style lang="scss" scoped>
  ::v-deep {
    .el-dialog--center .el-dialog__body {
      padding: 0;
    }
  }
  iframe {
    width: 100%;
    display: block;
  }
</style>

参考

https://blog.csdn.net/q2qwert/article/details/130905525
https://blog.csdn.net/KK_vicent/article/details/130827910

Logo

前往低代码交流专区

更多推荐