Vue集成OnlyOffice组件实现在线预览
侧边栏壁纸
  • 累计撰写 174 篇文章
  • 累计收到 1,068 条评论

Vue集成OnlyOffice组件实现在线预览

萧瑟
2022-12-26 / 1 评论 / 693 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2022年12月26日,已超过484天没有更新,若内容或图片失效,请留言反馈。

前言

最近有个项目需要预览上传的附件(如:PDF、Excel、Word等),且效果要好,Vue插件中也有对应的插件:表格使用 xlsx 、文档使用 docx-prrviewpdf 则使用iframe内嵌网页实现,公司的OA也是这样实现的,但是效果极差,之前使用zfile 搭建私有网盘发现了一个 OnlyOffice 组件,实属不错,刚好对接一下,实现了附件预览。

简介

OnlyOffice 是一个包含常用办公套件,WordExcelPPT大办公套件搬到了云端,只需要一个浏览器即可以在线使用 Office 的各种功能。

预览文件类型:

1、text(.doc, .docm, .docx, .dot, .dotm, .dotx, .epub, .fodt, .htm, .html, .mht, .odt, .ott, .pdf, .rtf, .txt, .djvu, .xps);
2、spreadsheet(.csv, .fods, .ods, .ots, .xls, .xlsm, .xlsx, .xlt, .xltm, .xltx);
3、presentation(.fodp, .odp, .otp, .pot, .potm, .potx, .pps, .ppsm, .ppsx, .ppt, .pptm, .pptx).

工作原理

1、用户使用文档管理器打开文档进行查看或者编辑。(基于浏览器访问)
2、使用JavaScript API 将文档唯一标识符(key)以及文档URL(url)发送到文档编辑器。
3、文档编辑器向文档编辑服务发送一个打开文档的请求。
4、文档编辑服务从文档存储服务下载相对应的文档,并将文档转换为Office Open XML格式。
5、准备就绪后,文档编辑服务会将转化后的文档传输到基于浏览器的文档编辑器。
6、提供编辑或者查看权限,对文档进行相应操作,执行保存

搭建服务(docker)

参考zfile 部署文档-自建 OnlyOffice

docker run --restart=always --name onlyoffice \
    -p 8081:80 \
    -e JWT_ENABLED=false \
    -v /app/onlyoffice/DocumentServer/logs:/var/log/onlyoffice \
    -v /app/onlyoffice/DocumentServer/data:/var/www/onlyoffice/Data \
    -v /app/onlyoffice/DocumentServer/lib:/var/lib/onlyoffice \
    -v /app/onlyoffice/DocumentServer/db:/var/lib/postgresql \
    onlyoffice/documentserver

集成教程

引入 js 脚本

public/index.html 引入搭好的文档解析api ,其中ip:port为docker部署的地址,本文地址为10.10.84.233:8081 ,详见源码demo

<script type='text/javascript' src='http://ip:port/web-apps/apps/api/documents/api.js'></script>

组件封装

新建组件页面: src/components/only-office/preview.vue 代码如下

<!-- only office 编辑器-->
<template>
  <div id='onlyOfficePreview'></div>
</template>

<script>
export default {
  name: 'onlyOfficePreview',
  props: {
    option: {
      type: Object,
      default: () => {
        return {}
      },
    },
  },
  data() {
    return {
      doctype: '',
      docEditor: null,
    }
  },
  beforeDestroy() {
    if (this.docEditor !== null) {
      this.docEditor.destroyEditor();
      this.docEditor = null;
    }
  },
  watch: {
    option: {
      handler: function (n) {
        this.setEditor(n)
        this.doctype = this.getFileType(n.fileType)
      },
      deep: true,
    },
  },
  mounted() {
    if (this.option.url) {
      this.setEditor(this.option)
    }
  },
  methods: {
    async setEditor(option) {
      if (this.docEditor !== null) {
        this.docEditor.destroyEditor();
        this.docEditor = null;
      }
      this.doctype = this.getFileType(option.fileType)
      let config = {
        document: {
          //后缀
          fileType: option.fileType,
          key: option.key || '',
          title: option.title,
          permissions: {
            //是否可以编辑: 只能查看,传false
            edit: option.isEdit,
            print: option.isPrint,
            download: false,
            //是否可以填写表格,如果将mode参数设置为edit,则填写表单仅对文档编辑器可用。 默认值与edit或review参数的值一致。
            // "fillForms": true,
            //跟踪变化
            // "review": true
          },
          url: option.url,
        },
        documentType: this.doctype,
        editorConfig: {
          //"编辑word后保存时回调的地址,这个api需要自己写了,将编辑后的文件通过这个api保存到自己想要的位置
          callbackUrl: option.editUrl,
          //语言设置
          lang: option.lang,
          //定制
          customization: {
            //是否自动保存
            autosave: false,
            chat: false,
            comments: false,
            help: false,
            // "hideRightMenu": false,//定义在第一次加载时是显示还是隐藏右侧菜单。 默认值为false
            //是否显示插件
            plugins: false,
          },
          user: {
            id: option.user.id,
            name: option.user.name
          },
          mode: option.model ? option.model : 'edit',
        },
        width: '100%',
        height: '100%',
        token: option.token || ''
      }

      // eslint-disable-next-line no-undef,no-unused-vars
      this.docEditor = new DocsAPI.DocEditor('onlyOfficePreview', config)

    },
    getFileType(fileType) {
      let docType = ''
      let fileTypesDoc = [
        'doc', 'docm', 'docx', 'dot', 'dotm', 'dotx', 'epub', 'fodt', 'htm', 'html', 'mht', 'odt', 'ott', 'pdf', 'rtf', 'txt', 'djvu', 'xps',
      ]
      let fileTypesCsv = [
        'csv', 'fods', 'ods', 'ots', 'xls', 'xlsm', 'xlsx', 'xlt', 'xltm', 'xltx',
      ]
      let fileTypesPPt = [
        'fodp', 'odp', 'otp', 'pot', 'potm', 'potx', 'pps', 'ppsm', 'ppsx', 'ppt', 'pptm', 'pptx',
      ]
      if (fileTypesDoc.includes(fileType)) {
        docType = 'text'
      }
      if (fileTypesCsv.includes(fileType)) {
        docType = 'spreadsheet'
      }
      if (fileTypesPPt.includes(fileType)) {
        docType = 'presentation'
      }
      return docType
    }
  },
}
</script>

组件调用

App.vue中修改如下

<template>
  <div id="app">
    <div class='qualityManual-container'>
      <div style="margin-bottom: 10px">
        <el-button style='width: 120px;' type='primary' @click='previewPdf'>预览PDF文档</el-button>
        <el-button style='width: 120px;' type='primary' @click='previewExcel'>预览Excel文档</el-button>
        <el-button style='width: 120px;' type='primary' @click='close'>关闭</el-button>
      </div>
      <div v-if='show' class='qualityManual-container-office'>
        <only-office-preview :option='option'/>
      </div>
    </div>
  </div>
</template>

<script>
import onlyOfficePreview from '@/components/only-office/preview.vue'

export default {
  name: 'App',
  components: {
    onlyOfficePreview
  },
  data() {
    return {
      //参考vabOnlyOffice组件参数配置
      option: {
        url: '',
        isEdit: '',
        fileType: '',
        title: '',
        lang: '',
        isPrint: '',
        user: {id: null, name: ''}
      },
      show: false,
    }
  },
  methods: {
    // 预览PDF
    previewPdf(){
      this.show = true
      this.option.isEdit = false
      this.option.lang = 'zh-CN'
      this.option.url = 'http://10.10.84.234:9000/file/Spring Boot2系列实战教程0726.pdf'
      this.option.title = 'Spring Boot2系列实战教程0726'
      this.option.fileType = 'pdf'
      this.option.isPrint = false
      this.option.user = {id: 12, name: '测试'}
    },
    // 预览Excel
    previewExcel(){
      this.show = true
      this.option.isEdit = false
      this.option.lang = 'zh-CN'
      this.option.url = 'http://10.10.84.234:9000/file/可视化数据分析看板图形图表1.xlsx'
      this.option.title = '可视化数据分析看板图形图表1'
      this.option.fileType = 'xlsx'
      this.option.isPrint = false
      this.option.user = {id: 12, name: '测试'}
    },
    close() {
      this.show = false
    },
  },
}
</script>

<style>
/*#app {*/
/*  font-family: Avenir, Helvetica, Arial, sans-serif;*/
/*  -webkit-font-smoothing: antialiased;*/
/*  -moz-osx-font-smoothing: grayscale;*/
/*  text-align: center;*/
/*  color: #2c3e50;*/
/*  margin-top: 60px;*/
/*}*/
html, body {
  height: 100%;
}

#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  height: 100%;

}

.qualityManual-container {
  padding: 0 !important;
  height: 100%;
}

.qualityManual-container-office {
  width: 100%;
  height: calc(100% - 55px);
}
</style>

启动服务,效果如下

excel预览1

excel预览2

pdf预览

Demo下载

only-office-preview

参考文章

zfile使用文档:自建OnlyOffice服务

评论 (1)

取消
  1. 头像
    yearn19
    辽宁省沈阳市 Windows 10 · Google Chrome

    尊敬的独立博客作者您好,您的博客已经被收录在博客乌托邦,博客乌托邦是一个中文独立博客文章聚合搜索平台,如有疑问可前往https://utopiablog.cn 留言,祝您新春愉快!

    回复