vue 在线预览 word ,Excel,pdf,图片 数据流 内网文件流 亲测有效(word 目前支持docx文件以及doc文件(doc需要后端处理))

注:doc转 docx后端转数据流  谷歌 114 版本以上会解析错误! 

 如果是需要更好的体验:可以使用 kkFileView - 在线文件预览

需要后端在服务器部署一个服务 之后返回地址前端进行直接在线访问;(支持内网哦) 

需求:在线预览文件(doc,docx,xls,xlsx,img,pdf)其他类型下载

如果你要是公网 那直接参考在线office 引入url地址 直接预览(本文是返回数据流  不是公网)

效果图:

xls :代码效果

xls:office效果

 doc :代码效果

doc :office效果

 pdf 效果

图片效果

pdf 直接用的浏览器自带的

excel 插件 xlsx

docx 插件  docx-preview

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

也是查阅了好多东西也借鉴了许多人的代码,亲测有效! 拿过去换地址 直接就能用

html 代码

<template>
  <div class="viewItemFile">
    <!-- 预览文件 -->
    <el-dialog
      width="100%"
      class="viewItemFileDialog"
      title="预 览"
      :visible.sync="dialogVisible"
      :before-close="innerhandleClose"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
    >
        //判断类型
      <div class="image" v-if="type == 'image'">
        <div>
          <el-image :src="imgUrl" :preview-src-list="srcList"> </el-image>
        </div>
      </div>
      <div class="docWrap" v-if="type == 'doc'">
        <!-- 预览文件的地方(用于渲染) -->
        <div ref="file"></div>
      </div>
      <div v-if="type == 'xls'">
        <div class="excel-view-container">
          <div id="excelView" v-html="excelView"></div>
        </div>
      </div>
        // pdf用嵌套的iframe
      <div v-if="type == 'pdf'">
        <iframe
          :src="pdfurl"
          type="application/x-google-chrome-pdf"
          width="100%"
          height="100%"
        />
      </div>
    </el-dialog>
  </div>
</template>

script

methods:{
// 前一个页面调用的init  我在前一个页面根据文件名字后缀已经判断是什么类型的文件了
init(file, type) {
      this.type = type;
      if (type == "image") {
axios
          .request({
            method: "GET", //这个不解释了吧
            url: '后端接口', //路径
            responseType: "blob", //告诉服务器想到的响应格式
            headers: {
              Accept: "application/octet-stream",
            },
          })
          .then((res) => {
            console.log(res);
            if (res) {
              let blob = new Blob([res.data], { type: "image/jpeg" });
              const imageUrl = URL.createObjectURL(blob);
              this.imgUrl = imageUrl;
              this.srcList = [imageUrl],;
              that.loading = true;
            } else {
              that.$notify.error({ title: "失败", message: "接口请求失败" });
              that.loading = false;
            }
          })
          .catch(function (error) {
            that.$notify.error({ title: "失败", message: "接口请求失败" });
            console.log(error);
            that.loading = false;
          });
        
      } else if (type == "pdf") {
 axios
          .request({
            method: "GET", //这个不解释了吧
            url: '后端地址'//路径
            responseType: "blob", //告诉服务器想到的响应格式
            headers: {
              "Content-Type": "application/pdf;charset=UTF-8",
            },
          })
          .then((res) => {
            console.log(res);
            if (res) {
              let blob = new Blob([res.data], { type: "application/pdf" });
              const url = URL.createObjectURL(blob);
              console.log(url);
              
              that.loading = false;
              this.pdfurl = url;
            } else {
              that.$notify.error({ title: "失败", message: "接口请求失败" });
              that.loading = false;
            }
          })
          .catch(function (error) {
            that.$notify.error({ title: "失败", message: "接口请求失败" });
            console.log(error);
            that.loading = false;
          });
        
      } else if (type == "xls") {
        //表格
        var that = this;
        axios
          .request({
            method: "GET", //这个不解释了吧
            url: '后端地址', //路径
            responseType: "arraybuffer", //告诉服务器想到的响应格式
            headers: {
              "Content-Type":
                "application/vnd.ms-excel;application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
            },
          })
          .then((res) => {
            console.log(res);
            if (res) {
              const workbook = XLSX.read(new Uint8Array(res.data), {
                type: "array",
              }); // 解析数据
              const worksheet = workbook.Sheets[workbook.SheetNames[0]]; // workbook.SheetNames 下存的是该文件每个工作表名字,这里取出第一个工作表
              this.excelView = XLSX.utils.sheet_to_html(worksheet); // 渲染
              this.$nextTick(function () {
                // DOM加载完毕后执行,解决HTMLConnection有内容但是length为0问题。
                this.setStyle4ExcelHtml();
              });
            } else {
              that.$notify.error({ title: "失败", message: "接口请求失败" });
              that.loading = false;
            }
          })
          .catch(function (error) {
            that.$notify.error({ title: "失败", message: "接口请求失败" });
            console.log(error);
            that.loading = false;
          });
      } else if (type == "doc") {
            // word
        var that = this;
        axios
          .request({
            method: "GET", //这个不解释了吧
            url: '后端地址' //路径
            responseType: "blob", //告诉服务器想到的响应格式
          })
          .then((res) => {
            console.log(res);
            if (res) {
              let docx = require("docx-preview");
              docx.renderAsync(res.data, this.$refs.file);
            } else {
              that.$notify.error({ title: "失败", message: "接口请求失败" });
              that.loading = false;
            }
          })
          .catch(function (error) {
            that.$notify.error({ title: "失败", message: "接口请求失败" });
            console.log(error);
            that.loading = false;
          });
      }

      this.dialogVisible = true;
    },
    // 设置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");
              }
            }
          }
        }
      }
    },
}

css 有需要的 自行添加

<style lang="scss" scoped>
.viewItemFile {
  .image {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    div {
      height: 600px;
      width: 600px;
    }
  }
  .divContent {
    display: flex;
    align-items: center;
    justify-content: center;
  }
  /deep/ .el-dialog {
    margin: 0 !important;
    height: 100vh !important;
    .el-dialog__footer {
      margin-bottom: 30px;
      padding: 0px;
    }
  }
  /deep/ .el-dialog__body {
    height: 96%;
    width: 100%;
    padding: 0;
    overflow: auto;
  }
}
.viewItemFile {
  /deep/ table {
    width: 100% !important;
    border-collapse: collapse !important;
    border-spacing: 0 !important;
    text-align: center !important;
    border: 0px !important;
    overflow-x: auto !important;
  }

  /deep/ table tr td {
    /* border: 1px solid gray !important; */
    border-right: 1px solid gray !important;
    border-bottom: 1px solid gray !important;
    width: 300px !important;
    height: 33px !important;
  }
  /**整体样式 */
  /deep/ .excel-view-container {
    background-color: #ffffff;
  }
  /**标题样式 */
  /deep/ .class4Title {
    font-size: 22px !important;
    font-weight: bold !important;
    padding: 10px !important;
  }
  /**表格表头样式 */
  /deep/ .class4TableTh {
    /* font-size: 14px !important; */
    font-weight: bold !important;
    padding: 2px !important;
    background-color: #ccc !important;
  }
}
</style>
<style lang="scss">
.viewItemFileDialog {
  overflow: hidden;
  .el-dialog__header {
    padding: 10px 20px 10px;
    background-color: #19a199;
  }
  .el-dialog__header .el-dialog__title {
    font-size: 15px;
    color: #ffffff;
    font-weight: 700;
  }
  .dialog-footer {
    display: flex;
    justify-content: center;
  }
  .search-btn {
    background: #19a8a6;
    color: white;
    border: none;
    height: 30px;
    padding: 0px 20px;
  }

  .el-dialog__headerbtn .el-dialog__close {
    color: #ffffff;
  }
  .well {
    display: block;
    background-color: #f2f2f2;
    border: 1px solid #ccc;
    margin: 0px;
    width: 100%;
    height: 100%;
    overflow: auto;
  }
}
</style>

文件流

excel 文件流  其他的就不都发了

doc 文件需要后端转成docx文件流返回  之后直接用docx插件搞定!

参考地址:java doc转docx

xls 引用之处

doc 引用之处

  • 31
    点赞
  • 216
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 40
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

new Vue()

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值