关于vue实现在线word编辑功能 onlyOffice

11,673 阅读2分钟

前言

在上一个vue2的项目中,牵扯到了一个在线编辑的功能,当时我第一时间想到的是利用富文本去转换成word文档实现编辑功能,但是这显然是不行的。后面用了两套方案,

1.第一套是wps开发平台:

这个需要利用公司去申请,在调用对方的api接口,是需要花费费用,当时调试了几天,各种困难迎难而上, 一直没能调试成功,也问了官网人员。只能怪自己太菜了。 下面这传代码是调用wps的一个实例:通过 UMD 的形式引入 JSSDK 后,会在全局对象上挂载一个 WebOfficeSDK 对象,我们可以通过该对象提供的 init()函数完成文档的初始化。 appId与fileId是必须传的参数, 具体的内容还是去wps开放平台好好看看官方文档。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>WebOffice</title>
</head>
<script src="./web-office-sdk-solution.umd.js"></script>
<body>
  <script>
    window.onload = () => {
      const instance = WebOfficeSDK.init({
        officeType: WebOfficeSDK.OfficeType.Writer,
        appId: 'xxxxx',
        fileId: 'xxxxx'
      })
    }
  </script>
</body>
</html>

2.第二套是onlyoffice:

首先要将官方文档中的API安装到服务器里面,然后拿到api在服务器的静态地址,用script标签引入到项目的 index.html 文件中,引入的地址为api在服务器的地址,官方文档的地址是不可用的,需要自己配,配置好这一步才能让后面onlyoffice实例化的时候用起来。下面两个地址一个为onlyoffice官网,一个为中文网,感兴趣的小伙伴可以去看看

第一步在index.html引入api.vue

<script type="text/javascript" src="https://documentserver/web-apps/apps/api/documents/api.js"></script>

第二步创建组件每次用可以直接调用:

<template>
   <div>
     <div id='vabOnlyOffice'></div>
   </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 属性的变化,当 option 发生改变时,调用相应的处理函数
       option: {
         handler: function(n) {
           this.setEditor(n)
           this.doctype = this.getFileType(n.fileType)
         },
         deep: true,
       },
     },
     mounted(){//组件挂载后,检查option.url是否存在,如果存在则调用setEditor方法进行编辑器的初始化设置
       if (this.option.url) {
         this.setEditor(this.option)
       }
     },
      methods: {
       async setEditor(option) { //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 ||'' ,          // 唯一值key
             title: option.title,            // 指定在编辑器中显示的文件名称
             permissions: {                  //
               edit: option.isEdit,          //是否可以编辑: 只能查看,传false
               print: option.isPrint,        
               download: option.isDownload,  
               fillForms: true,              //是否可以填写表格,如果将mode参数设置为edit,则填写表单仅对文档编辑器可用。 默认值与edit或review参数的值一致。
               review: true                  //跟踪变化
             },
             url: option.url,                // 指定需打开加载文档的URL
           },
           documentType: this.doctype,
           editorConfig: {
             callbackUrl: option.callbackUrl, //编辑word后保存时回调的地址,这个回调用于后端接收你改变后的数据
             lang: option.lang,              //语言设置
             chat: {
               autosave: true,              //是否自动保存
               chat: false,
               comments: false,
               help: false,
               //是否显示插件
               plugins: false,
             },
             user:{   // 用户信息
               id:option.user.id,
               name:option.user.name
             },
             mode:option.model?option.model:'edit',
           },
           events: {
             onAppReady: this.onAppReady,   // 调用此方法 应用程序被加载到浏览器中。
             onDocumentStateChange:this.onDocumentStateChange,		//文档被修改。
           },
           width: '100%',       	// 定义浏览器窗口中的档高度(默认为 100%)。
           height: '800px',        // 定义浏览器窗口中的文档宽度(默认为 100%)。
           token:option.token||""  // 安全令牌  
         }
         console.log('---config111----',config)
         this.docEditor = new DocsAPI.DocEditor('vabOnlyOffice', config)
       },
       onDocumentStateChange(event){},  // 当文档被修改后调用
       onAppReady() {   //onAppReady 方法是一个回调函数,当 OnlyOffice 编辑器加载完成后调用
         this.connector = this.docEditor.createConnector();  // 创建connector连接器
         console.log(this.docEditor,'+++++++创建connector连接器创建connector连接器创建connector连接器++++++');
       },
 
       getFileType(fileType) { // getFileType 方法用于根据文件类型(fileType)返回对应的文档类型(docType)
         let docType = ''
         let fileTypesDoc = [
             'doc', 'docm', 'docx', 'dot', 'dotm', 'dotx', 'epub', 'fodt', 'htm', 'html', 'mht', 'odt', 'ott', 'pdf', 'rtf', 'txt', 'djvu', 'xps','word',
         ]
         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>
          <!-- onlyoffice展示 -->
           <div class='qualityManual-container'>
               <div v-if='show' class='qualityManual-container-office'>
                   <vab-only-office :option='option' />
               </div>
           </div>

</template>
<script>
import vabOnlyOffice from '@/VabOnlyOffice/index.vue'
export default {
   components: { vabOnlyOffice},
 data() {
   return {
        //参考vabOnlyOffice组件参数配置
           option: {
               url: '',
               callbackUrl:'', // 关闭弹窗后 回调用callbackurl接口进行保存  
               fileType: '',   //文件扩展名 
               key: '',        //key 默认置空则不走缓存 always updat
               title: '',  //查看或编辑的文档定义所需的文件名,该文件名在下载文档时也将用作文件   
               isEdit: true,               // 是否可以编辑: 只能查看,传false 
               isDownload:false,           // 是否下载 
               lang: 'zh-CN',              // 语言:zh-CN简体中文/en英文           
               isPrint: true,              // 启用导出                                                 
               user: {
                 id: 1111, 
                 name: '张三李四'                                               
               }
           },      
       show: false,      // 弹窗关闭

   }

   };
 },
 methods: {
   //这里的val是传递的参数
   loadOnlyOffice(val){
           this.option.key =        // key 默认置空则不走缓存
           this.option.title = ''   // 该文件名在下载文档时也将用作文件名
           this.option.url =        // 定义存储原始查看或编辑的文档的绝对URL
           this.option.fileType ='docx'                // 文件类型
           this.option.callbackUrl=''                  // 回调地址
           this.show = true                        // 打开onlyOffice窗口
           console.log(val,'编辑word默认配置参数')
       },
};
</script>

<style lang="less" scoped>
 .qualityManual-container {
   padding: 0 !important;
   width: 100%;
   height:calc( 100vh - 180px);
 }
 .qualityManual-container-office {
   width: 100%;
   height: calc(100% - 55px);
 }
</style>

引用一张调用成功后的案例 v2-4055a183aee3d3af682abb58a28461fb_b.webp

组件中的 events 里面还有很多种方法,具体还是去看官网,这样子会更清楚些。

当时为了能在项目中 编辑修改word 查找了大量的资料,试过富文本 问过wps的工作人员 最后觉得onlyOffice更复合当前项目就使用了,由于能力有限, 还第一次写文章,如有写都不好的请多多包含