使用 Spire.WordJS 在 React 中实现在线 Word 文档编辑

在数字化转型浪潮中,越来越多的企业与开发者开始将文档处理能力迁移至纯前端体系,以提升应用的响应速度、安全性和易用性。传统的 Word 文档编辑往往依赖本地 Office 软件或复杂的后端服务,而随着 Web 技术的成熟,在浏览器中直接完成 Word 文档的创建、编辑与导出已成为现实。

本文将介绍一款强大的前端文档编辑控件------ Spire.WordJS ,并手把手教你如何将其集成到 React 项目中,快速构建一个功能完整的在线 Word 文档编辑器。

什么是 Spire.WordJS?

Spire.WordJS 是 E-ICEBLUE 推出的纯前端 Word 文档在线编辑器组件。它基于 WebAssembly 技术, 无需安装 Microsoft Office,也无需依赖后端服务 ,即可在浏览器中完成从打开文档到编辑、再到导出的完整文档处理流程。

作为 Spire.OfficeJS 套件的核心组件之一,Spire.WordJS 涵盖了 Word、Excel、PowerPoint、PDF 等多种格式的查看、编辑、创建与转换能力。

核心功能亮点

1. 可视化编辑,提升团队效率

实时显示编辑者光标和评论,内嵌评论及评论解决流程让团队协作更高效。

2. 高保真兼容 Word

采用成熟解析引擎,最大程度保留原文件的排版、样式、表格、页眉页脚和脚注,确保文档打开后无需额外手动调整。

3. 高级格式编辑器

提供丰富的样式设置功能,包括标题、正文、引用等,支持自定义样式模板,实现企业统一模板一键应用。

4. 企业级安全与权限管理

支持基于角色的访问控制,可为用户分配只读、编辑或评论权限;支持静态文件加密存储。

5. 智能文档批注与标记

支持文字高亮、下划线、删除线、批注和标签管理,便于团队在审阅或校对文档时快速标记重点内容。

6. 丰富的表格与图文处理功能

支持插入、编辑表格、图片和图形对象,可调整尺寸、样式和排版。

7. 跨平台访问与云端存储

支持 Web 和桌面端访问,实现文档云端存储与同步。

为什么选择 Spire.WordJS?

  • 企业级兼容性 :与 Microsoft Office 高度兼容,最大限度保留文档排版与样式
  • 无需安装、即开即用 :纯 Web 端体验,支持主流浏览器
  • 可扩展的 API 与集成能力 :提供完善的 REST API 和 SDK,便于集成到现有系统
  • 高可用与安全合规 :支持多区域部署与自动备份策略
  • 灵活方案与个性化配置 :提供多种授权与使用方案,支持按需定制

在 React 中集成 Spire.WordJS

接下来,我们将一步步完成 Spire.WordJS 在 React 项目中的集成。

步骤一:安装 Node.js

首先下载安装 Node.js。安装完成后,在命令行中验证版本:

复制代码
node -v
npm -v

步骤二:使用 Vite 创建 React 项目

在指定目录下执行以下命令创建项目:

复制代码
npm create vite@latest my-officejs-app -- --template react

步骤三:安装依赖

进入项目目录,安装路由管理库:

复制代码
cd my-officejs-app
npm install react-router-dom

步骤四:集成 Spire.OfficeJS

下载 Spire.OfficeJS 产品包。

Windows 环境 :双击运行解压包下的 run_genallfonts.bat 文件。

Linux 环境 :使用命令 sh run_genallfonts.sh start 运行。

运行完成后,web 文件夹下会多出 fontsweb 文件夹)。

在 React 项目的 public 目录下新建 spire.cloud 文件夹,将包含 fontsweb 的整个 web 文件夹复制到该目录下。

步骤五:构建文件上传与编辑器页面

App.jsx - 路由与状态管理
复制代码
import { createContext, useContext, useState } from 'react';
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import Home from './Home';
import Editor from './Editor';

const FileContext = createContext();
export const useFileStore = () => useContext(FileContext);

function FileProvider({ children }) {
  const [file, setFile] = useState(null);
  const [fileUint8Data, setFileUint8Data] = useState(null);
  return (
    <FileContext.Provider value={{ file, setFile, fileUint8Data, setFileUint8Data }}>
      {children}
    </FileContext.Provider>
  );
}

const router = createBrowserRouter([
  { path: '/', element: <Home /> },
  { path: '/editor', element: <Editor /> },
]);

function App() {
  return (
    <FileProvider>
      <RouterProvider router={router} />
    </FileProvider>
  );
}

export default App;
Home.jsx - 文件上传功能

实现拖拽上传、选择本地文件、使用 FileReader 将文件转为 Uint8Array:

复制代码
import { useRef, useEffect } from 'react';
import { useFileStore } from './App';
import { useNavigate } from 'react-router-dom';

function Home() {
  const { setFile, setFileUint8Data } = useFileStore();
  const navigate = useNavigate();
  const fileInput = useRef();

  useEffect(() => {
    // 阻止默认拖放行为
    ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
      document.addEventListener(eventName, preventDefaults, false);
    });
    document.addEventListener('drop', handleDrop, false);
  }, []);

  const preventDefaults = (e) => {
    e.preventDefault();
    e.stopPropagation();
  };

  const handleDrop = async (e) => {
    const file = e.dataTransfer?.files[0];
    if (!file) return;
    const uint8Data = await readFileAsUint8Array(file);
    setFile(file);
    setFileUint8Data(uint8Data);
    navigate('/editor');
  };

  const readFileAsUint8Array = (file) => {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onload = () => {
        const arrayBuffer = reader.result;
        resolve(new Uint8Array(arrayBuffer));
      };
      reader.onerror = reject;
      reader.readAsArrayBuffer(file);
    });
  };

  return (
    <div>
      <h2>文件上传</h2>
      <p>拖放文件到浏览器 或</p>
      <input type="file" ref={fileInput} onChange={handleDrop} />
    </div>
  );
}

export default Home;

说明 :FileReader 用于读取本地文件,Uint8Array 是 OfficeJS 的 WebAssembly 接收的二进制格式。

Editor.jsx - 集成编辑器
复制代码
import { useRef, useEffect } from 'react';
import { useFileStore } from './App';
import { useNavigate } from 'react-router-dom';

function Editor() {
  const { file, fileUint8Data } = useFileStore();
  const navigate = useNavigate();
  const config = useRef({});
  const originUrl = window.location.origin;

  useEffect(() => {
    if (!file) {
      navigate('/');
      return;
    }
    loadScript();
  }, []);

  const loadScript = () => {
    const script = document.createElement('script');
    script.setAttribute('src', '/spire.cloud/web/editors/spireapi/SpireCloudEditor.js');
    script.onload = initEditor;
    document.head.appendChild(script);
  };

  const initEditor = () => {
    initConfig();
    const editor = new SpireCloudEditor.OpenApi('iframeEditor', config.value);
    window.Api = editor.GetOpenApi();
  };

  const initConfig = () => {
    config.value = {
      fileAttrs: {
        fileInfo: {
          name: file.name,
          ext: getFileExtension(),
          primary: String(new Date().getTime()),
          creator: 'User',
          createTime: new Date().toLocaleString()
        },
        sourceUrl: originUrl + '/files/' + file.name,
        createUrl: originUrl + '/open',
        mergeFolderUrl: '',
        fileChoiceUrl: '',
        templates: {}
      },
      user: {
        id: 'uid-1',
        name: 'User',
        canSave: true
      },
      editorAttrs: {
        editorMode: 'edit',
        editorWidth: '100%',
        editorHeight: '100%',
        editorType: 'document',
        platform: 'desktop',
        viewLanguage: 'zh',
        isReadOnly: false,
        canChat: true,
        canComment: true,
        canReview: true,
        canDownload: true,
        canEdit: true,
        canForcesave: true,
        embedded: {
          saveUrl: '',
          embedUrl: '',
          shareUrl: '',
          toolbarDocked: 'top'
        },
        useWebAssemblyDoc: true,
        useWebAssemblyExcel: true,
        useWebAssemblyPpt: true,
        spireDocJsLicense: '',
        spireXlsJsLicense: '',
        spirePresentationJsLicense: '',
        spirePdfJsLicense: '',
        serverless: {
          useServerless: true,
          baseUrl: originUrl,
          fileData: fileUint8Data
        },
        events: {
          onSave: onFileSave
        },
        plugins: {
          pluginsData: []
        }
      }
    };
  };

  const getFileExtension = () => {
    const filename = file.name.split(/[\\/]/).pop();
    return filename.substring(filename.lastIndexOf('.') + 1).toLowerCase() || '';
  };

  const onFileSave = (data) => {
    console.log('保存数据:', data);
    // 在这里实现保存逻辑:发送到服务器或下载文件等
  };

  return <div id="iframeEditor"></div>;
}

export default Editor;

配置说明

  • editorType:设置为 "document" 表示 Word 文档编辑器
  • viewLanguage:可设为 "zh""en"
  • useWebAssemblyDoc:启用 WebAssembly 以提升性能
  • serverless:Serverless 模式直接使用文件数据,无需后端服务器
main.jsx - 入口配置
复制代码
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import App from './App.jsx';

createRoot(document.getElementById('root')).render(<App />);

注意 :StrictMode 会导致编辑器渲染两次,建议在生产环境中禁用。

vite.config.js - 端口配置
复制代码
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  server: {
    host: '0.0.0.0',
    port: 8050
  },
  plugins: [react()]
});

步骤六:运行项目

复制代码
npm run dev

访问 http://localhost:8050 即可体验在线 Word 文档编辑功能。

总结

通过以上步骤,我们成功在 React 项目中集成了 Spire.WordJS,实现了一个功能完整的在线 Word 文档编辑器。整个过程无需安装 Microsoft Office,也无需搭建复杂的后端服务

Spire.WordJS 凭借其 高保真兼容、丰富的编辑功能、企业级安全管控以及灵活的集成能力 ,为开发者提供了一个轻量、高效、易集成的文档处理解决方案。无论是构建在线文档平台、知识库、教育平台,还是各类管理后台,Spire.WordJS 都能帮助你快速落地文档编辑能力。

相关推荐
大大大大晴天1 小时前
聊聊Flink的几种血缘方案
前端·flink
消失的旧时光-19431 小时前
KMP Web 开发实战(二):js、wasmJs、browser、executable 到底是什么意思?
开发语言·前端·javascript·跨平台·kmp
宇图SHARE1 小时前
别再用 Python 写 Agent 前端了!Vue3 + NestJS + TypeScript 全栈方案,开发效率翻倍
前端·后端
IT_陈寒1 小时前
Python的GIL让我以为CPU跑满了,结果...
前端·人工智能·后端
禅思院1 小时前
AI对话前端从入门到崩溃:一个长对话引发的五层优化战争【六】
前端·架构·前端框架
冷小鱼2 小时前
AI Agent 的核心算法:多智能体协作(Multi-Agent Systems)
前端·人工智能·算法·multi-agent·多智能体协作·systems
速易达网络2 小时前
在线web文本图片绘图系统
word
qq_422152572 小时前
PDF页面管理的几种实用方法:拆分、合并、删除指定页面
java·前端·pdf
qq_212838972 小时前
后端Node.js + MySQL,前端Html+js,Nginx反向代理快速部署WEB项目
前端·mysql·node.js