【预览word文档】使用插件 docx-preview 预览线上 word 文档

目录

效果展示

代码

html 复制代码
<!-- 文书预览弹窗 -->
<template>
  <el-dialog :visible.sync="dialogVisible" width="80%" top="5vh" @close="close">
    <template #title>
      <div class="dialog_title">
        <span>{{ file.wjmc }}</span>
        <el-button type="primary" size="mini" icon="el-icon-download">下载</el-button>
      </div>
    </template>

    <el-carousel ref="ElCarouselRef" :autoplay="false" arrow="always" :initial-index="fileIndex" @change="carouselChange">
      <el-carousel-item v-for="(item, index) in fileList" :key="index">
        <template v-if="['.pdf'].includes(item.wjgs)">
          <embed :src="item.wjlj" type="application/pdf" width="100%" height="100%" />
        </template>
        <template v-else-if="['.doc', '.docx'].includes(item.wjgs)">
          <!-- 【主要代码】word文档预览 -->
          <div class="word" :ref="`word_container_${index}`" />

          <div v-show="wordLoading[index]" class="word_loading">
            <i class="el-icon-loading"></i>正在加载文档...
          </div>
          <div v-show="item.showFail && index in wordLoading && !wordLoading[index]" class="word_error">
            <i class="el-icon-document-delete"></i>文档渲染失败
          </div>
        </template>
        <template v-else>
          <el-image :src="item.wjlj" fit="cover" :preview-src-list="[item.wjlj]"></el-image>
        </template>
      </el-carousel-item>
    </el-carousel>
  </el-dialog>
</template>

<script>
import Axios from 'axios' // 方法二获取线上文件
import * as docx from 'docx-preview' // 【主要代码】使用到的插件

export default {
  name: 'FlwsPreviewDialog',
  components: {},
  props: {
    fileList: {
      type: Array,
      default: () => [
        {
          wjlj: '/XXX/p4OmsfvdjAN8f2h2tp23Q==.pdf',
          wjmc: '测试.pdf',
          wjgs: '.pdf'
        },
        {
          wjlj: '/XXX/Hmeydz0LjY1DPrk0OY4WJw==.docx',
          wjmc: '测试.docx',
          wjgs: '.docx'
        },
        {
          wjlj: '/XXX/KRcIS5uN4jN8uW+yOnI3Q==.png',
          wjmc: '截图_①.png',
          wjgs: '.png'
        },
        {
          wjlj: '/XXX/zOU3u8F7mYewaL2dCmPCkg==.png',
          wjmc: '截图-button.png',
          wjgs: '.png'
        },
        {
          wjlj: '/XXX/uYIy0yhNFSTFrIC5fW2Zw==.jpg',
          wjmc: '高拍仪扫描文件_1766988435595.jpg',
          wjgs: '.jpg'
        }
      ]
    }
  },

  data() {
    return {
      dialogVisible: false,
      fileIndex: 0,
      wordLoading: {}
    }
  },

  computed: {
    file() {
      return this.fileList[this.fileIndex] || {}
    }
  },

  methods: {
    open(index) {
      this.fileIndex = index
      this.dialogVisible = true
      this.getDoc()
      this.$refs.ElCarouselRef?.setActiveItem(this.fileIndex)
    },
    getDoc() {
      // 【主要代码】word文档预览处理
      this.fileList.forEach((i, index) => {
        if (['.doc', '.docx'].includes(i.wjgs) && i.wjlj && !(index in this.wordLoading)) {
          this.wordLoading[index] = true

          setTimeout(() => {
            this.handleFileChange(i.wjlj, index)
          }, 2000)
        }
      })
    },

    async handleFileChange(url, index) {
      try {
        /** ** 【主要代码】方法一 fetch 获取线上文件 start ****/
        const response = await fetch(url) // 获取线上文件
        const arrayBuffer = await response.arrayBuffer()

        await docx.renderAsync(
          arrayBuffer,
          this.$refs[`word_container_${index}`][0],
          null,
          this.getOptions()
        )
        /** ** 【主要代码】方法一 fetch 获取线上文件 end ****/

        /** ** 【主要代码】方法二 axios 获取线上文件 start ****/
        // Axios.get(url, {
        //   responseType: 'arraybuffer'
        // }).then((res) => { // 获取线上文件
        //   docx.renderAsync(
        //     res.data,
        //     this.$refs[`word_container_${index}`][0],
        //     null,
        //     this.getOptions()
        //   )
        // })
        /** ** 【主要代码】方法二 axios 获取线上文件 end ****/
      } catch (error) {
        // this.$message.error('文档渲染失败')
        this.fileList[index].showFail = true

        console.error('渲染失败:', error)
      } finally {
        this.wordLoading[index] = false
        this.$forceUpdate()
      }
    },

    getOptions() {
      return {
        className: 'docx',
        inWrapper: true,
        ignoreWidth: false,
        ignoreHeight: false,
        ignoreFonts: false,
        breakPages: true,
        debug: false,
        experimental: false,
        trimXmlDeclaration: true,
        useBase64URL: false,
        useMathMLPolyfill: true,
        showChanges: false,
        ignoreLastRenderedPageBreak: true
      }
    },
    carouselChange(index) {
      this.fileIndex = index
    },
    close() {
      this.dialogVisible = false
      this.fileIndex = 0
    }
  }
}
</script>

<style lang='scss' scoped>
::v-deep .el-dialog {
  .dialog_title {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding-right: 27px;
  }
  .el-dialog__headerbtn {
    top: 15px;
  }

  .el-dialog__body {
    height: 85vh;
    .el-carousel {
      width: 100%;
      height: 100%;
      .el-carousel__container {
        height: 100%;
        position: relative;

        .el-image {
          width: 100%;
          height: 100%;
        }

        .word {
          width: 100%;
          height: 100%;
          overflow: auto;
        }
        .word_loading,
        .word_error {
          position: absolute;
          top: 50%;
          left: 50%;
          transform: translate(-50%, -50%);
          text-align: center;
          i {
            display: block;
            font-size: 50px;
            margin-block: 10px;
          }
        }
      }
    }
  }
}
</style>
相关推荐
superman超哥2 小时前
Rust 发布 Crate 到 Crates.io:从本地到生态的完整旅程
开发语言·后端·rust·crate·crates.io
浪客川2 小时前
【百例RUST - 002】流程控制 基础语法练习题
开发语言·rust
一路往蓝-Anbo2 小时前
C语言从句柄到对象 (二) —— 极致的封装:不透明指针与 SDK 级设计
c语言·开发语言·数据结构·stm32·单片机·嵌入式硬件
上天_去_做颗惺星 EVE_BLUE2 小时前
C++学习:学生成绩管理系统
c语言·开发语言·数据结构·c++·学习
雪域迷影2 小时前
使用Python库获取网页时报HTTP 403错误(禁止访问)的解决办法
开发语言·python·http·beautifulsoup·urllib
chao1898442 小时前
基于Qt的SSH/FTP远程文件管理与命令执行实现方案
开发语言·qt·ssh
凯子坚持 c2 小时前
Qt常用控件指南(1)
开发语言·数据库·qt
Flash.kkl2 小时前
Python基础语法
开发语言·python
十五年专注C++开发2 小时前
CMake进阶:find_package使用总结
开发语言·c++·cmake·跨平台编译