前端预览word几种方案

一、问题引入

前端需要预览word文档

二、解决方案

1.mammoth.js(不推荐)

页面代码

<el-upload class="upload-demo" action="https://jsonplaceholder.typicode.com/posts/" :on-preview="handlePreview"
      :on-remove="handleRemove" :before-remove="beforeRemove" :file-list="fileList" :on-success="handleSuccess">
      <el-button size="small" type="primary">点击上传</el-button>
    </el-upload>
    <div v-html="wordHtml"></div>

js代码

handlePreview(file) {
      console.log(file, this.$refs.contentRef);
      const reader = new FileReader()
      reader.readAsArrayBuffer(file.raw)
      reader.onload = e => {
        const data = reader.result
        mammoth.convertToHtml({ arrayBuffer: data }).then(res => {
          console.log('res', res);
          this.wordHtml = res.value
        }).catch(error => {
          console.log('error', error);
        })
      }
    },

说明:很多样式会丢失,如:标题栏不居中,本来是 Word 中的排序默认样式 1 2 3,跟现有的协议规范样式不匹配,超链接没有交互,Table 表格不符合预期等等;

2.docx-preview

  • 使用本地上传文件

上传文件js代码

handlePreview(file) {
      console.log(file, this.$refs.contentRef);
      const reader = new FileReader()
      reader.readAsArrayBuffer(file.raw)
      reader.onload = e => {
        const data = reader.result
        docx.renderAsync(data, this.$refs.contentRef);
      }
    },
  • 使用接口返回文件流
  // 预览
    goPreview() {
      axios({
        method: "get",
        responseType: "blob", // 因为是流文件,所以要指定blob类型
        url: "http://xxx:10000/getDoc", // 自己的服务器,提供的一个word下载文件接口
      }).then(({ data }) => {
        console.log(data); // 后端返回的是流文件
        docx.renderAsync(data, this.$refs.contentRef); // 渲染到页面
      });
    },
    // 下载
    downLoad() {
      axios({
        method: "get",
        responseType: "blob", // 因为是流文件,所以要指定blob类型
        url: "http://ashuai.work:10000/getDoc", // 自己的服务器,提供的一个word下载文件接口
      }).then(({ data }) => {
        console.log(data); // 后端返回的是流文件
        const blob = new Blob([data]); // 把得到的结果用流对象转一下
        var a = document.createElement("a"); //创建一个<a></a>标签
        a.href = URL.createObjectURL(blob); // 将流文件写入a标签的href属性值
        a.download = "出师表.docx"; //设置文件名
        a.style.display = "none"; // 障眼法藏起来a标签
        document.body.appendChild(a); // 将a标签追加到文档对象中
        a.click(); // 模拟点击了a标签,会触发a标签的href的读取,浏览器就会自动下载了
        a.remove(); // 一次性的,用完就删除a标签
      });
    },

说明:样式还原度一半,无分页;某些版本有报错,需搭配 jszip.js 包使用

3.vue-office

  • 一站式:提供word(.docx)、pdf、excel(.xlsx, .xls)、ppt(.pptx)多种文档的在线预览方案。
  • 简单:只需提供文档的src(网络地址)即可完成文档预览。
  • 体验好:选择每个文档的最佳预览方案,保证用户体验和性能都达到最佳状态。
  • 性能好:针对数据量较大做了优化。
# docx文档预览,基于docx-preview库实现
npm install @vue-office/docx

# excel文档预览,基于exceljs和x-data-spreadsheet实现,全网样式支持更好
npm install @vue-office/excel

# pdf文档预览,基于pdfjs库实现,实现了虚拟列表增加性能
npm install @vue-office/pdf

# pptx文档预览,基于pptx-preview实现
npm install @vue-office/pptx

代码样例:

<template>
  <div class="document-wrapper">
    <VueOfficeDocx :src="fileData" />
  </div>
</template>

<script lang="ts" setup>
import { ref } from "vue";
import axios from "axios";
import VueOfficeDocx from '@vue-office/docx'

const fileData = ref<any>(null);

function getDocxContent() {
  // 注意:本地静态文件需要放放在public目录下
  axios.get('/test.docx', { responseType: 'arraybuffer' }).then((res) => {
    fileData.value = res.data;
  }).catch((err) => { console.log(err) })
}
getDocxContent();

</script>

<style lang="less">
.document-wrapper {
  margin: 10px;
}
</style>

 

posted @ 2025-04-27 19:51  盼星星盼太阳  阅读(933)  评论(0)    收藏  举报