vue整合onlyOffice实现文档在线预览编辑


前言

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

一、服务组成

ONLYOFFICE文档服务分为客户端和服务端两部分。

客服端包括:
文档管理器(Document manager)
文档编辑器(Document editor)

服务端包括:
文档存储服务(Document storage service)
文档编辑服务(Document editing service)
文档指令服务(Document command service)
文档转换服务(Document conversion service)
文档构建服务(Document builder service)

二、工作原理

1.打开文件

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

2.保存文件

1、用户在文档编辑器中编辑文件。
2、文档编辑器将更改发送给文档编辑服务。
3、用户关闭文档编辑器。
4、文档编辑服务监视到文档结束工作,并收集从文档编辑器发送到一个文档中的更改
5、执行回调保存接口
6、返回状态
在这里插入图片描述

2.协同编辑

1、用户1和用户2在文档编辑器中打开同一个文档,即打开文件时已使用一个相同的document.key
2、用户1对打开的文档进行更改。
3、文档编辑器将用户1所做的更改发送到文档编辑服务。
4、文档编辑服务将用户1所做的更改发送给用户2文档编辑器。
5、现在用户2可以看到这些变化。
在这里插入图片描述

搭建服务

官网传送门https://helpcenter.onlyoffice.com/installation/docs-developer-install-ubuntu.aspx?from=api_csharp_example

一.docker搭建文档服务器

1.安装docker

2.拉取镜像

sudo docker pull onlyoffice/documentserver 

3.运行镜像

创建数据目录

# 创建对应目录
mkdir logs
mkdir data
mkdir lib
mkdir db
ls
# 启动docker容器,默认启动端口为80,可以进行修改
docker run -i -t -d -e TZ="Asia/Shanghai" -p 6831:80 --restart=always \
    -v /root/data/onlyoffice/DocumentServer/logs:/var/log/onlyoffice  \
    -v /root/data/onlyoffice/DocumentServer/data:/var/www/onlyoffice/Data  \
    -v /root/data/onlyoffice/DocumentServer/lib:/var/lib/onlyoffice \
    -v /root/data/onlyoffice/DocumentServer/db:/var/lib/postgresql  onlyoffice/documentserver
    
# 查看镜像下载
docker images

# 查看容器
docker ps

# 查看启动日志
docker logs -f 容器ID

访问 localhost:6831/welcome测试是否成功

二.配置使用

1.预览文件

###支持的文档类型
# 5.4.2 版本
# 字符串类型,定义文档打开类型:
1text(.doc, .docm, .docx, .dot, .dotm, .dotx, .epub, .fodt, .htm, .html, .mht, .odt, .ott, .pdf, .rtf, .txt, .djvu, .xps);
2spreadsheet(.csv, .fods, .ods, .ots, .xls, .xlsm, .xlsx, .xlt, .xltm, .xltx);
3presentation(.fodp, .odp, .otp, .pot, .potm, .potx, .pps, .ppsm, .ppsx, .ppt, .pptm, .pptx).

public/index.html引入搭好的文档解析api

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

2.vue组件封装

<!--onlyoffice 编辑器-->
<template>
  <div id='vabOnlyOffice'></div>
</template>

<script>
  export default {
    name: 'VabOnlyOffice',
    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: {
              edit: option.isEdit,//是否可以编辑: 只能查看,传false
              print: option.isPrint,
              download: false,
              // "fillForms": true,//是否可以填写表格,如果将mode参数设置为edit,则填写表单仅对文档编辑器可用。 默认值与edit或review参数的值一致。
              // "review": true //跟踪变化
            },
            url: option.url,
          },
          documentType: this.doctype,
          editorConfig: {
            callbackUrl: option.editUrl,//"编辑word后保存时回调的地址,这个api需要自己写了,将编辑后的文件通过这个api保存到自己想要的位置
            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('vabOnlyOffice', 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>

组件调用

<template>
  <div id="app">
    <div class='qualityManual-container'>
        <div>
          <button style='width: 120px;' type='primary' @click='getFile'>测试预览office文档</button>
          <button style='width: 120px;' type='primary' @click='close'>关闭</button>
        </div>
        <div v-if='show' class='qualityManual-container-office'>
          <vab-only-office :option='option' />
        </div>
  </div>
  </div>
</template>

<script>
import vabOnlyOffice  from './components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    vabOnlyOffice
  },
  data() {
      return {
        //参考vabOnlyOffice组件参数配置
        option: {
          url: '',
          isEdit: '',
          fileType: '',
          title: '',
          lang: '',
          isPrint: '',
          user: { id:null,name:''}
        },
        show: false,
      }
    },
    methods: {
      getFile() {
        this.show = true
        // getAction('/file/selectById', { id: this.id }).then(res => {
        this.option.isEdit = false
        this.option.lang = 'zh-CN'
        this.option.url = 'http://ip:port/a.xlsx'
        this.option.title = '123'
        this.option.fileType = 'xlsx'
        this.option.isPrint = false
        this.option.user= { id:12,name:'张三'}
        // })
      },
      close() {
        this.show = false
      },
    },
}
</script>

<style>
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>

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐