Vue实现文档在线预览功能,上传预览PDF、Word等office文件

1、Office Web(微软的开发接口)

优点

  1. 没有 Office也可以直接查看Office 文件
  2. 适用于移动端、PC
  3. 无需下载文件就可以在浏览器中查看

<iframe src="文档地址"  frameborder="0" />

const docUrl = '外网可预览的地址'
const url = encodeURIComponent(docUrl)
const officeUrl = 'http://view.officeapps.live.com/op/view.aspx?src=' + url
// 在新窗口打开编码后 的链接
window.open(officeUrl, '_target')

const documentUrl = '' // 将此替换为你的Word文档的URL
const officeOnlineViewerUrl = 'https://view.officeapps.live.com/op/view.aspx?src='
// 第一种
// this.previewUrl = officeOnlineViewerUrl + encodeURIComponent(documentUrl)

// 第二种
// this.previewUrl = `${officeOnlineViewerUrl}${documentUrl}&embedded=true`

// 没有下载按钮的--https://view.officeapps.live.com/op/embed.aspx?src=

// 有下载按钮的--https://view.officeapps.live.com/op/view.aspx?src=

2、XDOC文档预览云服务(预览pdf、word、xls、ppt) 

 XDOC文档预览云服务

 注意:文档地址要用utf-8编码,并且外网可访问。

优点:

  1. 只需要传入文档URL,基于内容自动识别文档格式
  2. 高效、快速、实时预览,重复请求0毫秒响应
  3. 使用HTML5方式展现内容,同时适配PC端和移动端
  4. 支持PDF,OFD,DOC/X,XLS/X,PPT/X,JPG,MP4等多种文档格式

调用方法

https://view.xdocin.com/view?src=文档地址(https://)

eg:
const url = 'https://view.xdocin.com/view?src=文档地址【https(http)://】可预览的地址'

JS调用:
https://view.xdocin.com/view?src=https%3A%2F%2Fview.xdocin.com%2Fdemo%2Fview.docx

 可选参数

  1. &pdf=true,word文档尝试以pdf方式显示,默认false
  2. &watermark=水印文本,显示文本水印;“img:”+图片url表示图片水印,如:img:https://view.xdocin.com/demo/wm.png
  3. &saveable=true,是否允许保存源文件,默认false
  4. &printable=false,是否允许打印,默认true
  5. ©able=false,是否允许选择复制内容,默认true
  6. &toolbar=false,是否显示底部工具条,默认true
  7. &title=自定义标题
  8. &expire=30,预览链接有效期,单位分钟,默认永久有效
  9. &limit=,限制页数,如:“5”表示只显示前5页,“2,5”表示从第2页开始的5页,对pdf/doc/docx/ppt/pptx有效
  10. &filename=文件名,辅助识别文档格式
  11. &fontsize=字体大小(单位px),默认14,范围:6~58
  12. &mtime=文件修改时间戳(如:1633093801,精确到秒)或修改时间(如:2021-10-01 21:10:01),值改变刷新缓存

 

<template>
  <iframe
  :src="xsrc"
  frameborder="0"
  scrolling="auto"
  style="width:100%;height:100%;"
  ></iframe>
</template>

<script>
export default {
  name: 'XdocView',
  data () {
    return {
      xsrc: ''
    }
  },
  props: {
    src: String,
    watermark: String
  },
  watch: {
    src: {
      handler (val) {
        this.genXsrc()
      },
      immediate: true
    },
    watermark: {
      handler (val) {
        this.genXsrc()
      },
      immediate: true
    }
  },
  methods: {
    genXsrc () {
      if (this.src) {
        // 你的文档地址
        const file = this.src
        // XDOC文档预览服务地址
        let xurl = 'https://view.xdocin.com/view?src='
        // 传入文档地址
        xurl += encodeURIComponent(file)
        // 预览参数
        const ops = {
          watermark: this.watermark,
          // pdf: true, // word文档尝试以pdf方式显示,默认false
          // img: true, // 尝试以图片方式显示,默认false
          // "saveable": true, //是否允许保存源文件,默认false
          printable: false // 是否允许打印,默认true
          // "copyable": false, //是否允许选择复制内容,默认true
          // toolbar: false // 是否显示底部工具条,默认true
          // "expire": 30, //预览链接有效期,单位分钟,默认永久有效
          // "limit": "1,3", //限制页数,如:“5”表示只显示前5页,“2,5”表示从第2页开始的5页,对pdf/doc/docx/ppt/pptx有效
          // "mtime": 1633093801, //文件修改时间戳(精确到秒)或修改时间(如:2021-10-01 21:10:01),值改变刷新缓存,实时预览
        }
        // 传入预览参数
        for (const a in ops) {
          if (ops[a] != undefined) {
            xurl += '&' + a + '=' + encodeURIComponent(ops[a])
          }
        }
        // 开始预览
        this.xsrc = xurl
      }
    }
  }
}
</script>

<style>

</style>

3、插件预览

安装

//docx文档预览组件
npm install @vue-office/docx vue-demi
 
//excel文档预览组件
npm install @vue-office/excel vue-demi
 
//pdf文档预览组件
npm install @vue-office/pdf vue-demi

使用

<template>
  <div class="index">
    <div class="select-file">
      <input style="display: none" id="input" ref="previewRef" type="file">
      <el-button size="small" type="primary" @click="uploadBtn">点击上传</el-button>

      <el-button size="small" type="primary" @click="previewDoc">
        预览文件
      </el-button>
    </div>
    <div class="file-preview">
      <!-- Word -->
      <VueOfficeDocx
        v-if="fileType === 'word'"
        style="height: 650px;"
        :src="src" />

      <!-- Excel -->
      <VueOfficeExcel
        v-else-if="fileType === 'excel'"
        style="height: 650px;"
        :src="src" />

      <!-- Pdf -->
      <VueOfficePdf
        v-else-if="fileType === 'pdf'"
        style="height: 650px;"
        :src="src" />
      <!-- img -->
      <iframe
        v-else-if="fileType === 'image'"
        class="iframePreview"
        :src="src"
        frameborder="0"/>
    </div>
  </div>
</template>
<script>
import VueOfficeDocx from '@vue-office/docx'
import '@vue-office/docx/lib/index.css'

import VueOfficeExcel from '@vue-office/excel'
import '@vue-office/excel/lib/index.css'

import VueOfficePdf from '@vue-office/pdf'
import axios from 'axios'
import { matchFileType } from '@/utils/tools'
export default {
  data () {
    return {
      src: '',
      fileType: ''
    }
  },
  components: {
    VueOfficeDocx,
    VueOfficeExcel,
    VueOfficePdf
  },
  mounted () {
    this.addInputEventListener()
  },
  methods: {
    /*
     * application/msword;charset=utf-8
     * application/pdf;charset=utf-8
     * application/vnd.ms-excel
     */
    addInputEventListener () {
      const input = document.querySelector('#input')
      input.addEventListener('input', e => {
        const fileBlob = e.target.files[0]
        this.fileType = matchFileType(fileBlob.name)

        // 第一种方式(通过window.URL.createObjectURL将Blob文件流转为一个路径)
        this.src = window.URL.createObjectURL(new Blob([fileBlob]))

        // 第二种方式(转为base64编码)
        // const fileReader = new FileReader()
        // fileReader.readAsDataURL(fileBlob)
        // fileReader.onload = e => {
        //   this.src = e.target.result
        // }

        // 第三种方式(获取到buffer)
        // fileBlob.arrayBuffer().then(buffer => {
        //   this.src = buffer
        // })
      })
    },
    uploadBtn () {
      const previewRef = this.$refs.previewRef
      previewRef.click()
    },
    async previewDoc () {
      const URL = window.URL || window.webkitURL
      const url = '/upload/handle/2024/01/18/1701677366939-20240118172302.jpg'
      this.fileType = matchFileType(url)
      const res = await axios({
        url,
        method: 'get',
        responseType: 'blob'
      })
      try {
        const downloadUrl = new Blob([res.data], {
          type: res.data.type
        })
        this.src = URL.createObjectURL(downloadUrl)
      } catch (error) {
        console.log(error, 'error')
      }
    }
  }
}
</script>
<style>
.index {
  width: 100%;
  height: 100%;
  padding: 15px;
  box-sizing: border-box;
}
.select-file {
  width: 100%;
  border-bottom: 1px dashed #ccc;
  margin-bottom: 15px;
}
.file-preview {
  width: 100%;
  height: 650px;
  border: 1px dashed #007acc;
}
.docx-wrapper{
  background: none !important;
}
.iframePreview{
  width: 100%;
  height: 650px;
}
</style>

 matchFileType文件

/**
 * 根据文件名后缀区分 文件类型
 *
 * @param: fileName - 文件名称
 * @param: 数据返回 1) 无后缀匹配 - false
 * @param: 数据返回 2) 匹配图片 - image
 * @param: 数据返回 3) 匹配 txt - txt
 * @param: 数据返回 4) 匹配 excel - excel
 * @param: 数据返回 5) 匹配 word - word
 * @param: 数据返回 6) 匹配 pdf - pdf
 * @param: 数据返回 7) 匹配 ppt - ppt
 * @param: 数据返回 8) 匹配 视频 - video
 * @param: 数据返回 9) 匹配 音频 - radio
 * @param: 数据返回 10) 其他匹配项 - other
 */
export function matchFileType (fileName) {
  // 后缀获取
  let suffix = ''
  // 获取类型结果
  let result = ''
  // 路径为空判断
  if (!fileName) return false

  try {
    // 截取文件后缀
    suffix = fileName.substr(fileName.lastIndexOf('.') + 1, fileName.length)
    // 文件后缀转小写,方便匹配
    suffix = suffix.toLowerCase()
  } catch (err) {
    suffix = ''
  }
  // fileName无后缀返回 false
  if (!suffix) {
    result = false
    return result
  }
  const fileTypeList = [
    // 图片类型
    { typeName: 'image', types: ['png', 'jpg', 'jpeg', 'bmp', 'gif'] },
    // 文本类型
    { typeName: 'txt', types: ['txt'] },
    // excel类型
    { typeName: 'excel', types: ['xls', 'xlsx'] },
    { typeName: 'word', types: ['doc', 'docx'] },
    { typeName: 'pdf', types: ['pdf'] },
    { typeName: 'ppt', types: ['ppt'] },
    // 视频类型
    { typeName: 'video', types: ['mp4', 'm2v', 'mkv'] },
    // 音频
    { typeName: 'radio', types: ['mp3', 'wav', 'wmv'] }
  ]

  for (let i = 0; i < fileTypeList.length; i++) {
    const fileTypeItem = fileTypeList[i]
    const typeName = fileTypeItem.typeName
    const types = fileTypeItem.types
    result = types.some(function (item) {
      return item === suffix
    })
    if (result) {
      return typeName
    }
  }
  return 'other'
}

4、vue在浏览器局部预览world

1.引入下载

npm i docx-preview@0.1.4
npm i jszip

2.预览在线地址文件

<template>
  <div class="home">
    <div ref="file"></div>
  </div>
</template>

<script>
import axios from "axios";
const docx = require("docx-preview");
window.JSZip = require("jszip");
export default {
  mounted() {
    axios({
      method: "get",
      responseType: "blob", // 设置响应文件格式
      url: "请求地址",
    }).then(({ data }) => {
      docx.renderAsync(data, this.$refs.file); // 渲染到页面预览
    });
  },
};
</script>

3.预览本地文件

<template>
  <div class="outbox">
    <div class="my-component" ref="preview">
      <input type="file" @change="preview" ref="file" />
    </div>
  </div>
</template>
<script>
window.JSZip = require("jszip");
const docx = require("docx-preview"); // npm i docx-preview@0.1.4
export default {
  methods: {
    preview(e) {
      docx.renderAsync(this.$refs.file.files[0], this.$refs.preview); // 渲染到页面预览
    },
  },
};
</script>
<style lang="less" scoped>
.outbox {
  display: flex;
}
.my-component {
  width: 100%;
  height: 90vh;
  overflow: scroll;
  border: 1px solid #000;
}
/* 后面的提示文字颜色 */
[type='file'] {
  color: red;
}
/* 主按钮的样式自定义 */
::file-selector-button {
  height: 3rem;
  font-size: 1rem;
  color: #fff;
  border-radius: 0.25rem;
  border: 1px solid #2a80eb;
  padding: 0.75rem 1rem;
  background-color: #2a80eb;
  box-sizing: border-box;
  font-family: inherit;
  cursor: pointer;
}
</style>

5、word预览–mammoth.js

npm install --save mammoth

 <template>
  <div>
    <div id="wordView"
        v-html="vHtml" />
  </div>
</template>
<script>
import mammoth from 'mammoth'
export default {
  data () {
    return {
      vHtml: '',
      wordURL: '' // 文件地址
    }
  },
  created () {
    const vm = this
    const xhr = new XMLHttpRequest()
    xhr.open('get', this.wordURL, true)
    xhr.responseType = 'arraybuffer'
    xhr.onload = function () {
      if (xhr.status === 200) {
        mammoth
          .convertToHtml({ arrayBuffer: new Uint8Array(xhr.response) })
          .then(function (resultObject) {
            vm.$nextTick(() => {
              // document.querySelector("#wordView").innerHTML =
              //   resultObject.value;
              vm.vHtml = resultObject.value
            })
          })
      }
    }
    xhr.send()
  },
  methods: {}
}
</script>

  • 13
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
Vue2中实现在线预览Word文档的方法如下: 1. 首先,你需要调取接口获取后端传回的Word文档流。这可以通过调用接口的方法来完成,接口返回的文档流通常存储在res.data.data中。你可以使用axios或其他HTTP请求库来发送请求并接收响应。 2. 在Vue模板中,你可以创建一个按钮,通过点击按钮来触发预览Word文档的操作。按钮可以使用Element UI库的el-button组件或其他自定义的按钮组件。在按钮的点击事件处理函数中,调用接口方法并将返回的文档流作为参数传递给渲染函数。 3. 在Vue组件中引入docx-preview库,并使用其提供的renderAsync方法来渲染Word文档。你可以在组件的script标签中通过require语法引入docx-preview库,并在方法中使用docxx.renderAsync方法来渲染文档。渲染函数需要传递两个参数,第一个参数是接口返回的文档流,第二个参数是一个DOM元素的引用,用于指定渲染文档的位置。 下面是一个示例代码,演示了如何在Vue2中实现在线预览Word文档: ```html <template> <div> <el-button @click="previewWord">预览Word文档</el-button> <div ref="wordContainer"></div> </div> </template> <script> import { getWordDocument } from "@/api/documents"; var docxx = require("docx-preview"); export default { methods: { previewWord() { getWordDocument() // 调用接口获取文档流 .then((res) => { docxx.renderAsync(res.data.data, this.$refs.wordContainer); }) .catch((error) => { this.$message.error(error); }); }, }, }; </script> ``` 请注意,上述示例代码中的getWordDocument方法是一个示例接口调用方法,你需要根据实际情况替换为适用于你的项目的接口调用方法。此外,你还需要根据实际情况对代码进行调整和修改。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [vue实现预览word文档(处理文档流)](https://blog.csdn.net/weixin_45294459/article/details/126997364)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [vue实现pdf文档在线预览功能](https://download.csdn.net/download/weixin_38590784/13681693)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值