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>
相关推荐
郭老二6 小时前
【前端】vue3:编译步骤
前端
不在逃避q7 小时前
Trae/Vs Code/Cursor命令行无法跑npm命令
前端·arcgis·npm
夏殇之殁7 小时前
包中创建自定义列表项。 . 使用自定义列表项进行数据绑定 . 将天气预报数据保存到本地内存表,通过LiveBindings进行显示。 ...
服务器·前端·javascript
The Chosen One9857 小时前
高进度算法模板速记(待完善)
java·前端·算法
陈随易7 小时前
MoonBit抓包模块pcap,查看电脑的每一次联网通信
前端·后端·程序员
新中地GIS开发老师8 小时前
WebGIS开发学生作品|低空航天管理与航线规划系统
前端·javascript·webgis·三维gis开发
用户059540174468 小时前
大模型对话记忆持久化踩坑实录:用 Playwright 自动化测了 300 次,终于揪出会话丢失的真凶
前端·css
丙氨酸長鏈8 小时前
Web前端入门第 问:JavaScript 一个简单的 IndexedDB 数据库入门示例
前端·javascript·数据库
kyriewen9 小时前
面试官让我手写虚拟列表——AI生成的版本,快速滚动几下就白屏了
前端·javascript·面试
IT_陈寒9 小时前
Vite热更新失效?你可能漏了这个配置
前端·人工智能·后端