欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

在Vue项目里,用docx-preview插件实现在Express后端预览Word文档的方法

最编程 2024-02-22 10:17:48
...

问题描述

本文记录了一下预览word文档的功能。需要用到:

  • 前端:vue
  • 后端:express
  • 插件:docx-preview

思路分析

  1. 后端express代码中读取文件夹中的 .docx 类型文件
  2. 然后将其以可读流的方式返回给前端一个blob流文件
  3. 后端返回的流文件前端收到以后,执行docx-preview插件的renderAsync方法即可渲染出预览的效果

我们先看一下效果图

效果图

GIF 2021-11-24 10-22-13.gif

代码

后端express代码

// 引入文件模块 
const fs = require("fs")

// 返回word文件接口
route.get('/getDoc', (req, res) => {

  // 假设我们的word文档文件就存放在这个doc目录里面
  let docxUrl = './doc/出师表.docx'

  // 允许跨域
  res.header("Access-Control-Allow-Origin", "*");

  // 设置请求头
  res.writeHead(200, {
    // 指定文件类型为docx
    'Content-Type': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
  })

  //创建可读流
  let readStream = fs.createReadStream(docxUrl)

  // 将读取的结果以管道pipe流的方式返回给前端
  readStream.pipe(res);

})

前端vue代码

注意,vue项目要先下载插件哦

cnpm i docx-preview --save

<template>
  <div>
    <el-button @click="goPreview">点击预览word文件</el-button>
    <el-button @click="downLoad">点击下载word文件</el-button>
    <div class="docWrap">
      <!-- 预览文件的地方(用于渲染) -->
      <div ref="file"></div>
    </div>
  </div>
</template>

<script>
// 引入axios用来发请求
import axios from "axios";
// 引入docx-preview插件
let docx = require("docx-preview");
export default {
  mounted() {
    console.log("使用插件的renderAsync方法来渲染", docx); //
  },
  methods: {
    // 预览
    goPreview() {
      axios({
        method: "get",
        responseType: "blob", // 因为是流文件,所以要指定blob类型
        url: "http://ashuai.work:10000/getDoc", // 自己的服务器,提供的一个word下载文件接口
      }).then(({ data }) => {
        console.log(data); // 后端返回的是流文件
        docx.renderAsync(data, this.$refs.file); // 渲染到页面
      });
    },
    // 下载
    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标签
      });
    },
  },
};
</script>
<style lang="less" scoped>
.docWrap {
  // 指定样式宽度
  width: 900px;
  overflow-x: auto;
}
</style>

为了方便大家调试效果,所以后端接口我也提供了一份,大家如果不想写node接口直接用我的即可,接口在上述vue代码中,直接复制粘贴运行即可

总结

好记性不如烂笔头,如果帮到了您,欢迎动动您的小手点个赞呗 ^_^

pdf的预览最方便的做法就是使用浏览器自带的预览pdf功能,因为浏览器自带的预览功能,非常强大,并非一些pdfjs插件能比拟的。所以直接:window.open("http://ashuai.work:10000/getPdf"); 此接口是笔者服务器提供的pdf接口


2023.08.26更新 预览office文档(word、excel、ppt、pdf、png)简便方法

  • 上述的docx-preview插件只能预览简单的word文档(适合自己搞着玩)
  • 若是复杂的文档,甚至是excel、ppt,那问题还是没有解决,那这个时候有以下方案

方案一 不提供预览功能,想要看内容,用户需要下载再看

这种方式,的确很简便,不过用户体验不太好

方案二 使用微软提供的免费服务 //view.officeapps.live.com/op/view.aspx?src=xxxyyyzzz

  • 若是你的文件比较注重隐私,不能公开的话,这种方式,就不太适合了
  • 否者的话,是比较方便的解决方案
  • 这里需要你有一个自己的服务器
  • 并且服务器要购买域名对应
  • 要默认80端口哦,否则依旧是无法预览(笔者这里的也是80端口nginx转发了一下罢了)

笔者带大家回顾一下使用express搭建一个静态资源服务器

代码

// 引入express插件包并生成一个实例app
var express = require('express')
var app = express()

// 静态资源服务器
var path = require('path') // path路径用来找文件哦
var serveStatic = require('serve-static') // serve-static用来启动静态资源文件服务
const rootPath = path.join(__dirname, 'public') // 去哪里找呢?去public目录下找
app.use(serveStatic(rootPath)) // 注册即使用

// 在80端口上启动后端服务
app.listen(80, (req, res) => {
    console.log('后端服务端口地址为:  http://localhost:80');
    console.log('后端服务端口地址为:  http://127.0.0.1:80');
})

完整代码在github仓库:github.com/shuirongshu…

效果图

yulan.png

iframe使用

<template>
    <button @click="preview(value)" v-for="(key, value) in preDict" :key="key">{{ value }}</button>
    <br>
    <iframe v-if="staticSrc" :src="`https://view.officeapps.live.com/op/view.aspx?src=${encodeURIComponent(staticSrc)}`" />
</template>


<script setup>
import { ref } from "vue";
const staticSrc = ref('')
const preDict = {
    预览word: 'http://ashuai.work/api/word.docx',
    预览excel: 'http://ashuai.work/api/excel.xlsx',
    预览ppt: 'http://ashuai.work/api/ppt.pptx',
    预览pdf: 'http://ashuai.work/api/pdf.pdf',
    预览图片: 'http://ashuai.work/api/tree.png',
}
const preview = (params) => {
    if (params === '预览pdf' | params === '预览图片') {
        window.open(preDict[params], '_blank')
    } else {
        staticSrc.value = preDict[params]
    }
}
</script>
  
<style scoped>
button {
    margin: 0 12px;
    padding: 4px 8px;
    margin-bottom: 12px;
}

iframe {
    width: 900px;
    height: 600px;
}
</style>

方案三 自己公司搭建部署一套微软的office online server(免费)

  • office online server部署略微有点麻烦
  • 这个一般是后端同事去操作
  • 前端调用的话,还是使用iframe,同上类似

方案四

office预览功能 收费服务供应商,这个还挺多的,大家搜索一下,自行甄别即可