vue3使用ONLYOFFICE 实现在线Word,Excel等文档

vue3使用ONLYOFFICE 实现在线Word,Excel等文档

文章目录

安装

bash 复制代码
npm install @onlyoffice/document-editor-vue --save

创建组件OnlyOfficeEditor.vue

html 复制代码
<template>
  <div class="onlyoffice-editor" :style="{ height: height }">
    <DocumentEditor
      :id="id"
      :documentServerUrl="documentServerUrl"
      :config="mergedConfig"
      :events_onDocumentReady="handleDocumentReady"
      :events_onSave="handleSave"
      :events_onError="handleError"
      :events_onDestroy="handleDestroy"
      v-bind="$attrs"
    />
  </div>
</template>

<script setup>
import { ref, computed, watch } from 'vue';
import { DocumentEditor } from '@onlyoffice/document-editor-vue';

// 定义组件 props
const props = defineProps({
  // 编辑器唯一ID(默认自动生成)
  id: {
    type: String,
    default: () => `onlyoffice-editor-${Date.now()}`
  },
  // OnlyOffice 服务地址(必填)
  documentServerUrl: {
    type: String,
    required: true
  },
  // 文档配置(核心配置,必填)
  documentConfig: {
    type: Object,
    required: true,
    // 结构校验
    validator: (val) => {
      return val.document?.url && val.document?.fileType && val.document?.key;
    }
  },
  // 编辑器高度(默认800px)
  height: {
    type: String,
    default: '800px'
  },
  // 编辑模式(edit/view)
  mode: {
    type: String,
    default: 'edit',
    validator: (val) => ['edit', 'view'].includes(val)
  },
  // 语言(默认中文)
  lang: {
    type: String,
    default: 'zh-CN'
  }
});

// 定义组件事件
const emit = defineEmits([
  'document-ready',   // 文档加载完成
  'save',             // 保存事件
  'error',            // 错误事件
  'destroy',          // 组件销毁
  'custom-event'      // 自定义事件透传
]);

// 合并基础配置和用户配置
const mergedConfig = computed(() => {
  return {
    ...props.documentConfig,
    editorConfig: {
      // 基础配置(可被用户配置覆盖)
      mode: props.mode,
      lang: props.lang,
      // 合并用户传入的 editorConfig
      ...props.documentConfig.editorConfig,
      // 强制覆盖用户可能误设置的关键参数
      user: {
        ...props.documentConfig.editorConfig?.user,
        // 确保用户名存在(默认匿名)
        name: props.documentConfig.editorConfig?.user?.name || 'Anonymous'
      }
    }
  };
});

// 事件处理函数
const handleDocumentReady = () => {
  emit('document-ready');
};

const handleSave = (event) => {
  emit('save', event);
};

const handleError = (error) => {
  emit('error', error);
  console.error('OnlyOffice 错误:', error);
};

const handleDestroy = () => {
  emit('destroy');
};

// 监听模式变化,动态更新编辑器
watch(
  () => props.mode,
  (newMode) => {
    // 调用 OnlyOffice 实例方法切换模式
    const editor = window.DocEditor.getInstance(props.id);
    if (editor) {
      editor.setMode(newMode);
    }
  }
);

// 暴露给父组件的方法
defineExpose({
  // 手动触发保存
  saveDocument() {
    const editor = window.DocEditor.getInstance(props.id);
    if (editor) {
      editor.save();
    }
  },
  // 获取编辑器实例
  getEditorInstance() {
    return window.DocEditor.getInstance(props.id);
  }
});
</script>

<style scoped>
.onlyoffice-editor {
  width: 100%;
  overflow: hidden;
}
</style>

组件使用

html 复制代码
<template>
  <div>
    <button @click="handleManualSave">手动保存</button>
    <OnlyOfficeEditor
      ref="editorRef"
      :documentServerUrl="documentServerUrl"
      :documentConfig="docConfig"
      height="90vh"
      mode="edit"
      @document-ready="onDocReady"
      @save="onDocSave"
      @error="onDocError"
    />
  </div>
</template>

<script setup>
import OnlyOfficeEditor from '@/components/OnlyOfficeEditor.vue';
import { ref } from 'vue';
    
// 组件引用
const editorRef = ref(null);

// OnlyOffice 服务地址(替换为你的服务地址)
const documentServerUrl = ref('https://your-onlyoffice-server.com/');

// 文档配置(核心)
const docConfig = ref({
  document: {
    fileType: 'docx',
    key: 'doc-123456', // 文档唯一标识(建议用文件哈希)
    title: '测试文档.docx',
    url: 'https://your-server.com/files/test.docx' // 文档下载地址
  },
  editorConfig: {
    callbackUrl: 'https://your-server.com/api/onlyoffice/callback', // 保存回调地址
    user: {
      id: 'user-1',
      name: '张三' // 显示在编辑器中的名称
    },
    // 其他配置(如是否允许评论、打印等)
    allowComments: true,
    allowPrint: true
  }
});

// 事件处理
const onDocReady = () => {
  console.log('文档加载完成');
};

const onDocSave = (event) => {
  console.log('文档保存中', event);
};

const onDocError = (error) => {
  console.error('文档错误', error);
};

// 手动保存
const handleManualSave = () => {
  // 通过 ref 调用子组件方法
  editorRef.value?.saveDocument();
};
</script>
相关推荐
南知意-9 分钟前
3.3K Star ! 超级好用开源大屏设计器!
前端·开源·开源项目·工具·大屏设计
华仔啊1 小时前
Vue 组件通信的 8 种最佳实践,你知道几种?
前端·vue.js
POLITE31 小时前
Leetcode 234.回文链表 JavaScript (Day 9)
javascript·leetcode·链表
用户4445543654261 小时前
Android依赖的统一管理
前端
国家二级编程爱好者1 小时前
Android Lottie使用,如何自定义LottieView?
android·前端
南囝coding1 小时前
《独立开发者精选工具》第 025 期
前端·后端
@淡 定1 小时前
Dubbo + Nacos 完整示例项目
前端·chrome·dubbo
毕设源码-邱学长1 小时前
【开题答辩全过程】以 基于web的博客论坛系统的设计与实现为例,包含答辩的问题和答案
前端
就叫曲奇饼干吧1 小时前
前端面试题整理(方便自己看的)
前端·面试