npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@koi-br/office-provider-sdk

v1.0.37

Published

Universal Office Provider SDK supporting WPS, OnlyOffice and more. Framework-agnostic library for React, Vue, Angular, and vanilla JavaScript / 通用 Office 提供商 SDK,支持 WPS、OnlyOffice 等多种办公套件。框架无关库,支持 React、Vue、Angular 和原生 JavaScript

Downloads

653

Readme

Office Provider SDK

一个通用的 Office 提供商 SDK,支持 WPS、OnlyOffice 等多种办公套件。框架无关设计,完美适配 React、Vue、Angular 和原生 JavaScript。

A universal Office Provider SDK supporting WPS, OnlyOffice and more office suites. Framework-agnostic design, perfectly compatible with React, Vue, Angular, and vanilla JavaScript.


✨ 核心特性 / Core Features

  • 🌐 多Provider支持 - 统一 API 支持 WPS、OnlyOffice 等多种办公套件
  • 🚀 框架无关 - 可与 React、Vue、Angular 或原生 JavaScript 无缝集成
  • 🤖 智能配置 - 支持自动配置和手动配置两种模式
  • 📝 TypeScript 支持 - 完整的类型定义,提供出色的开发体验
  • 高性能 - 基于现代 JavaScript 模式,支持 Tree Shaking
  • 🛡️ 类型安全 - 严格的类型检查和运行时验证
  • 🔧 易于扩展 - 工厂模式设计,轻松添加新的 Provider

📦 安装 / Installation

npm install @koi-br/office-provider-sdk

主要导出 / Main Exports

// 主要初始化函数
import { initOfficeSDK } from '@koi-br/office-provider-sdk';

// 类型定义
import { 
  OfficeProviderType, 
  DocumentType,
  OfficeConfig,
  ReadyEventDetails,
  ErrorEventDetails
} from '@koi-br/office-provider-sdk';

// SDK 实例创建
import { createOfficeSDK, getGlobalOfficeSDK } from '@koi-br/office-provider-sdk';

// Provider 类(高级用法)
import { WPSProvider, OnlyOfficeProvider } from '@koi-br/office-provider-sdk';

// 工具函数
import { 
  createErrorHandler, 
  createReadyHandler,
  getSupportedProviders,
  isProviderSupported
} from '@koi-br/office-provider-sdk';

🚀 快速开始 / Quick Start

自动配置模式(推荐)/ Auto Configuration (Recommended)

import { initOfficeSDK } from '@koi-br/office-provider-sdk';

// 通过 API 自动获取配置
// 注意:configApiUrl 会自动拼接 '/api/office/online-office/config' 路径
const sdk = await initOfficeSDK({
  fileId: 'your-document-id',
  containerSelector: '#office-container',
  configApiUrl: 'https://api.example.com', // 基础URL,会自动拼接完整路径
  token: 'your-auth-token', // 可选:API认证令牌
  permissionToken: 'your-permission-token', // 可选:权限认证令牌
  isReadOnly: false,
  onReady: (provider, details) => {
    console.log('编辑器已就绪:', details);
  },
  onError: (error) => {
    console.error('编辑器错误:', error);
  }
});

// 使用统一的 API
await sdk.saveDocument();
await sdk.searchAndLocateText('Hello World!', true);

手动配置模式 / Manual Configuration

import { initOfficeSDK, OfficeProviderType, DocumentType } from '@koi-br/office-provider-sdk';

// WPS 手动配置
const wpsSDK = await initOfficeSDK({
  fileId: 'your-document-id',
  containerSelector: '#office-container',
  configApiUrl: '', // 手动模式下可以为空
  autoConfig: false,
  providerType: OfficeProviderType.WPS,
  manualConfig: {
    wps: {
      appId: 'your-wps-app-id',
      token: 'your-auth-token',
      refreshToken: 'your-refresh-token', // 可选
      documentType: DocumentType.WRITER, // 可选
      simple: false // 可选,是否使用简化模式
    }
  }
});

// OnlyOffice 手动配置
const onlyOfficeSDK = await initOfficeSDK({
  fileId: 'your-document-id',
  containerSelector: '#office-container',
  configApiUrl: '', // 手动模式下可以为空
  autoConfig: false,
  providerType: OfficeProviderType.ONLYOFFICE,
  manualConfig: {
    onlyoffice: {
      documentServerUrl: 'https://your-onlyoffice-server.com',
      token: 'your-jwt-token', // 可选:JWT安全令牌
      document: {
        fileType: 'docx',
        key: 'unique-document-key',
        title: 'Document.docx',
        url: 'https://example.com/document.docx',
        token: 'document-level-token' // 可选:文档级JWT令牌
      },
      editorConfig: { // 可选
        mode: 'edit', // 'edit' | 'view'
        callbackUrl: 'https://example.com/callback',
        user: {
          id: 'user-id',
          name: 'User Name'
        }
      },
      permissions: { // 可选
        edit: true,
        download: true,
        review: true,
        comment: true
      }
    }
  }
});

📚 API 参考 / API Reference

初始化配置 / Initialization Config

interface OfficeConfig {
  // 必需参数 / Required
  fileId: string;                    // 文档ID
  containerSelector: string;         // 容器选择器(CSS选择器,如 '#office-container')
  configApiUrl: string;             // 配置API基础地址(自动模式)
                                     // 实际请求URL为: configApiUrl + '/api/office/online-office/config?fileId=xxx&permissionToken=xxx'
  
  // 可选参数 / Optional
  isReadOnly?: boolean;             // 只读模式,默认 false
  autoConfig?: boolean;             // 自动配置,默认 true
  token?: string;                   // API认证令牌(用于Authorization头)
  permissionToken?: string;         // 权限认证令牌(用于API查询参数)
  
  // 手动配置参数 / Manual Configuration(autoConfig=false 时必需)
  providerType?: OfficeProviderType; // Provider类型('wps' | 'onlyoffice')
  manualConfig?: ManualProviderConfig; // 具体配置
  
  // 事件回调 / Event Callbacks
  onReady?: (provider: any, details?: ReadyEventDetails) => void;
  onError?: (error: ErrorEventDetails) => void;
}

统一文档操作 API / Unified Document API

// ========== 文本搜索和定位 ==========
// 搜索并定位文本(所有Provider支持)
await sdk.searchAndLocateText(text: string, highlight?: boolean);
// 根据文本定位(所有Provider支持)
await sdk.locateByText({ text: string });
// 搜索并替换(所有Provider支持)
await sdk.searchAndReplace({ old: string, new: string });

// ========== WPS 特有文本操作 ==========
// ⚠️ 以下方法仅在 WPS Provider 下可用
await sdk.insertTextAtCursor(text: string); // 在光标位置插入文本
await sdk.replaceText(pos: number, length: number, newText: string); // 替换指定位置内容
await sdk.getDocumentLength(); // 获取文档长度

// ========== 高亮操作 ==========
// ⚠️ 以下方法仅在 WPS Provider 下可用
await sdk.highlightText(pos: number, length: number); // 高亮指定范围
await sdk.clearHighlight(); // 清除所有高亮

// ========== 内容控制(所有Provider支持) ==========
// 添加内容控制字段
await sdk.addContentControl({ 
  fieldId: string, 
  placeholderText?: string 
});
// 设置内容控制的值
await sdk.setContentControlValue(fieldId: string, value: string);
// 删除内容控制
await sdk.removeContentControl(fieldId: string);
// 设置内容控制高亮颜色 [R, G, B, A]
await sdk.setControlsHighlight([255, 0, 0, 1]);

// ========== 文档管理 ==========
// 保存文档(所有Provider支持)
await sdk.saveDocument();
// 设置只读状态(所有Provider支持)
await sdk.setReadOnly(isReadOnly: boolean);

// ========== 评论相关(所有Provider支持) ==========
// 获取评论列表
await sdk.getCommentsList(key: string);
// 跳转到指定评论
await sdk.jumpCommentDto(jumpId: string, documentKey: string);

// ========== 视图操作(所有Provider支持) ==========
// 滚动到指定位置
await sdk.viewScrollToY(y: number);
// 适应宽度
await sdk.zoomFitToWidth();

// ========== 修订管理(WPS 特有) ==========
// ⚠️ 以下方法仅在 WPS Provider 下可用
await sdk.getRevisions(date?: string); // 获取修订信息
await sdk.handleRevisions(revisionIds: number[], action: 'accept' | 'reject'); // 处理修订
await sdk.acceptReviewByText({ old: string, new: string }); // 根据文本接受修订
await sdk.rejectReviewByText({ old: string, new: string }); // 根据文本拒绝修订

// ========== 格式化(WPS 特有) ==========
// ⚠️ 此方法仅在 WPS Provider 下可用
await sdk.formatDocumentFont({
  name?: string,    // 字体名称
  size?: number,   // 字体大小
  bold?: boolean,  // 是否粗体
  italic?: boolean, // 是否斜体
  color?: string   // 字体颜色(如 '#333333')
});

// ========== 高级用法 ==========
// 获取原生实例(所有Provider支持,但返回类型因Provider而异)
const nativeInstance = sdk.getNativeInstance();

Provider 管理 / Provider Management

// 获取当前 Provider 信息
const providerType = sdk.getCurrentProviderType(); // 返回 'wps' | 'onlyoffice' | null
const providerName = sdk.getCurrentProviderName(); // 返回 Provider 名称

// 检查就绪状态
const isReady = sdk.isReady; // boolean

// 获取支持的 Provider 列表
const providers = sdk.getSupportedProviders(); // Array<{ name: string, type: OfficeProviderType }>

// 切换 Provider(高级用法)
await sdk.switchProvider(newConfig);

// 销毁实例
await sdk.destroy();

工具函数 / Utility Functions

import { 
  createErrorHandler, 
  createReadyHandler,
  getSupportedProviders,
  isProviderSupported,
  createOfficeSDK,
  getGlobalOfficeSDK
} from '@koi-br/office-provider-sdk';

// 创建标准化的错误处理回调
const errorHandler = createErrorHandler((error) => {
  console.error('错误:', error.type, error.message);
});

// 创建标准化的就绪回调
const readyHandler = createReadyHandler((provider, details) => {
  console.log('就绪:', details.providerName);
});

// 获取支持的 Provider 列表
const providers = await getSupportedProviders();

// 检查是否支持指定 Provider
const isWpsSupported = await isProviderSupported(OfficeProviderType.WPS);

// 创建独立的 SDK 实例
const sdk1 = createOfficeSDK();
const sdk2 = createOfficeSDK();

// 获取全局 SDK 实例(单例)
const globalSDK = getGlobalOfficeSDK();

🌐 框架集成示例 / Framework Integration Examples

React 集成 / React Integration

import React, { useEffect, useRef, useState } from 'react';
import { initOfficeSDK } from '@koi-br/office-provider-sdk';

function OfficeEditor() {
  const [sdk, setSdk] = useState(null);
  const [isReady, setIsReady] = useState(false);

  useEffect(() => {
    const initEditor = async () => {
      try {
        const officeSDK = await initOfficeSDK({
          fileId: 'react-demo-doc',
          containerSelector: '#office-container',
          configApiUrl: 'https://api.example.com',
          token: 'your-auth-token',
          permissionToken: 'your-permission-token',
          onReady: (provider, details) => {
            setIsReady(true);
            console.log('React: 编辑器已就绪', details);
          },
          onError: (error) => {
            console.error('React: 编辑器错误', error);
          }
        });
        setSdk(officeSDK);
      } catch (error) {
        console.error('初始化失败:', error);
      }
    };

    initEditor();
    
    return () => {
      if (sdk) {
        sdk.destroy();
      }
    };
  }, []);

  const handleSearch = async () => {
    if (sdk && isReady) {
      await sdk.searchAndLocateText('搜索文本', true);
    }
  };

  const handleSave = async () => {
    if (sdk && isReady) {
      await sdk.saveDocument();
    }
  };

  return (
    <div>
      <div className="controls">
        <button onClick={handleSearch} disabled={!isReady}>
          搜索文本
        </button>
        <button onClick={handleSave} disabled={!isReady}>
          保存文档
        </button>
      </div>
      <div id="office-container" style={{ height: '600px' }} />
    </div>
  );
}

Vue 3 集成 / Vue 3 Integration

<template>
  <div>
    <div class="controls">
      <button @click="searchText" :disabled="!isReady">搜索文本</button>
      <button @click="saveDoc" :disabled="!isReady">保存文档</button>
    </div>
    <div id="office-container" style="height: 600px"></div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import { initOfficeSDK } from '@koi-br/office-provider-sdk';

const sdk = ref(null);
const isReady = ref(false);

onMounted(async () => {
  try {
    sdk.value = await initOfficeSDK({
      fileId: 'vue-demo-doc',
      containerSelector: '#office-container',
      configApiUrl: 'https://api.example.com',
      token: 'your-auth-token',
      permissionToken: 'your-permission-token',
      onReady: (provider, details) => {
        isReady.value = true;
        console.log('Vue: 编辑器已就绪', details);
      },
      onError: (error) => {
        console.error('Vue: 编辑器错误', error);
      }
    });
  } catch (error) {
    console.error('初始化失败:', error);
  }
});

onUnmounted(() => {
  if (sdk.value) {
    sdk.value.destroy();
  }
});

const searchText = async () => {
  if (sdk.value && isReady.value) {
    await sdk.value.searchAndLocateText('搜索文本', true);
  }
};

const saveDoc = async () => {
  if (sdk.value && isReady.value) {
    await sdk.value.saveDocument();
  }
};
</script>

Angular 集成 / Angular Integration

// office.service.ts
import { Injectable } from '@angular/core';
import { initOfficeSDK, type OfficeSDK } from '@koi-br/office-provider-sdk';

@Injectable({
  providedIn: 'root'
})
export class OfficeService {
  private sdk: OfficeSDK | null = null;
  private isReady = false;

  async initialize(config: any): Promise<void> {
    this.sdk = await initOfficeSDK({
      ...config,
      onReady: () => {
        this.isReady = true;
        console.log('Angular: 编辑器已就绪');
      },
      onError: (error) => {
        console.error('Angular: 编辑器错误', error);
      }
    });
  }

  async searchText(text: string): Promise<void> {
    if (this.sdk && this.isReady) {
      await this.sdk.searchAndLocateText(text, true);
    }
  }

  async saveDocument(): Promise<void> {
    if (this.sdk && this.isReady) {
      await this.sdk.saveDocument();
    }
  }

  destroy(): Promise<void> {
    if (this.sdk) {
      return this.sdk.destroy();
    }
    return Promise.resolve();
  }
}
// office.component.ts
import { Component, OnInit, OnDestroy } from '@angular/core';
import { OfficeService } from './office.service';

@Component({
  selector: 'app-office',
  template: `
    <div class="controls">
      <button (click)="searchText()">搜索文本</button>
      <button (click)="saveDocument()">保存文档</button>
    </div>
    <div id="office-container" style="height: 600px;"></div>
  `
})
export class OfficeComponent implements OnInit, OnDestroy {
  
  constructor(private officeService: OfficeService) {}

  async ngOnInit() {
    await this.officeService.initialize({
      fileId: 'angular-demo-doc',
      containerSelector: '#office-container',
      configApiUrl: 'https://api.example.com',
      token: 'your-auth-token',
      permissionToken: 'your-permission-token'
    });
  }

  async ngOnDestroy() {
    await this.officeService.destroy();
  }

  async searchText() {
    await this.officeService.searchText('搜索文本');
  }

  async saveDocument() {
    await this.officeService.saveDocument();
  }
}

原生 JavaScript / Vanilla JavaScript

<!DOCTYPE html>
<html>
<head>
  <title>Office Provider SDK Demo</title>
</head>
<body>
  <div class="controls">
    <button onclick="searchText()">搜索文本</button>
    <button onclick="saveDocument()">保存文档</button>
  </div>
  <div id="office-container" style="height: 600px;"></div>

  <script type="module">
    import { initOfficeSDK } from '@koi-br/office-provider-sdk';
    
    let sdk = null;
    let isReady = false;

    async function initializeOffice() {
      try {
        sdk = await initOfficeSDK({
          fileId: 'vanilla-demo-doc',
          containerSelector: '#office-container',
          configApiUrl: 'https://api.example.com',
          token: 'your-auth-token',
          permissionToken: 'your-permission-token',
          onReady: (provider, details) => {
            isReady = true;
            console.log('Vanilla JS: 编辑器已就绪', details);
          },
          onError: (error) => {
            console.error('Vanilla JS: 编辑器错误', error);
          }
        });
      } catch (error) {
        console.error('初始化失败:', error);
      }
    }

    window.searchText = async function() {
      if (sdk && isReady) {
        await sdk.searchAndLocateText('搜索文本', true);
      }
    };

    window.saveDocument = async function() {
      if (sdk && isReady) {
        await sdk.saveDocument();
      }
    };

    // 初始化
    initializeOffice();
  </script>
</body>
</html>

🔧 高级用法 / Advanced Usage

Provider 特定功能 / Provider-Specific Features

// 获取当前 Provider 类型
const providerType = sdk.getCurrentProviderType();

// WPS 特定功能
if (providerType === OfficeProviderType.WPS) {
  // WPS 特有的文本操作方法
  await sdk.insertTextAtCursor('文本内容');
  await sdk.replaceText(0, 5, '新文本');
  await sdk.highlightText(0, 10);
  await sdk.clearHighlight();
  
  // 获取文档长度
  const length = await sdk.getDocumentLength();
  
  // 格式化文档
  await sdk.formatDocumentFont({
    name: '微软雅黑',
    size: 14,
    bold: true,
    color: '#333333'
  });
  
  // 修订管理
  const revisions = await sdk.getRevisions();
  await sdk.handleRevisions([1, 2, 3], 'accept');
  await sdk.acceptReviewByText({ old: '旧文本', new: '新文本' });
  
  // 获取 WPS 原生实例(高级用法)
  const nativeInstance = sdk.getNativeInstance();
}

// OnlyOffice 特定功能
if (providerType === OfficeProviderType.ONLYOFFICE) {
  // 内容控制操作(所有Provider都支持,但OnlyOffice有更丰富的功能)
  await sdk.addContentControl({
    fieldId: 'custom-field',
    placeholderText: '请输入内容'
  });
  
  await sdk.setContentControlValue('custom-field', '字段内容');
  
  // 获取 OnlyOffice 原生实例(高级用法)
  const nativeInstance = sdk.getNativeInstance();
}

错误处理最佳实践 / Error Handling Best Practices

import { 
  initOfficeSDK, 
  createErrorHandler, 
  createReadyHandler 
} from '@koi-br/office-provider-sdk';

const sdk = await initOfficeSDK({
  fileId: 'your-document-id',
  containerSelector: '#office-container',
  configApiUrl: 'https://api.example.com/office/config',
  
  // 使用辅助函数创建标准化的回调
  onReady: createReadyHandler((provider, details) => {
    console.log(`${details.providerName} 已就绪`, details);
    // 自定义就绪逻辑
  }),
  
  onError: createErrorHandler((error) => {
    // 统一的错误处理
    switch (error.type) {
      case 'initialization_error':
        console.error('初始化失败:', error.message);
        break;
      case 'provider_switch_error':
        console.error('Provider 切换失败:', error.message);
        break;
      default:
        console.error('未知错误:', error);
    }
    
    // 可以添加错误上报、用户提示等逻辑
  })
});

多实例管理 / Multiple Instances

import { createOfficeSDK } from '@koi-br/office-provider-sdk';

// 创建多个独立的 SDK 实例
const sdkInstances = [];

for (let i = 0; i < 3; i++) {
  const sdk = createOfficeSDK();
  await sdk.initialize({
    fileId: `document-${i}`,
    containerSelector: `#office-container-${i}`,
    configApiUrl: 'https://api.example.com',
    token: 'your-auth-token',
    permissionToken: 'your-permission-token'
  }, {
    onReady: (provider, details) => {
      console.log(`实例 ${i} 已就绪:`, details);
    },
    onError: (error) => {
      console.error(`实例 ${i} 错误:`, error);
    }
  });
  sdkInstances.push(sdk);
}

// 统一操作所有实例
for (const sdk of sdkInstances) {
  await sdk.searchAndLocateText('批量操作文本', true);
  await sdk.saveDocument();
}

🛠️ 开发和构建 / Development & Build

# 安装依赖
npm install

# 开发模式(包含演示)
npm run dev

# 构建库
npm run build

# 构建演示
npm run build:example

# 清理构建文件
npm run clean

📁 项目结构 / Project Structure

office-provider-sdk/
├── src/
│   ├── core/                    # 核心 SDK 实现
│   │   ├── OfficeSDK.ts        # 主 SDK 类
│   │   └── OfficeProviderFactory.ts  # Provider 工厂
│   ├── providers/              # Provider 实现
│   │   ├── WPSProvider.ts      # WPS Provider
│   │   └── OnlyOfficeProvider.ts  # OnlyOffice Provider
│   ├── types/                  # TypeScript 类型定义
│   │   └── index.ts
│   ├── utils/                  # 工具函数
│   │   └── index.ts
│   └── index.ts               # 主入口文件(导出 initOfficeSDK 等)
├── examples/
│   ├── demo.vue               # Vue 3 完整演示
│   └── VueDemo.vue            # Vue 3 演示(备用)
├── dist/                      # 构建输出
├── sdk/                       # 外部 SDK 文件(WPS SDK等)
└── README.md

🌟 设计优势 / Design Advantages

统一抽象 / Unified Abstraction

  • 统一的 API 接口:无论使用哪种 Office 套件,都使用相同的方法调用
  • Provider 模式:可扩展的架构,轻松添加新的 Office 提供商
  • 类型安全:完整的 TypeScript 支持,编译时检查错误

智能配置 / Smart Configuration

  • 自动检测:通过 API 自动识别文档类型和 Provider
  • 配置分离:业务逻辑与具体 Provider 配置解耦
  • 降级支持:自动配置失败时可回退到手动配置

开发体验 / Developer Experience

  • 框架无关:可在任何前端技术栈中使用
  • 开箱即用:最少配置即可开始使用
  • 渐进增强:从简单使用到高级定制的平滑过渡

生产就绪 / Production Ready

  • 错误处理:完善的错误处理和回调机制
  • 性能优化:基于现代 JavaScript,支持 Tree Shaking
  • 可维护性:模块化设计,易于测试和维护

📖 更多示例 / More Examples

搜索和替换 / Search & Replace

// 搜索并高亮文本(所有Provider支持)
const result = await sdk.searchAndLocateText('目标文本', true);
if (result && typeof result === 'object' && result.found) {
  console.log(`找到文本,位置: ${result.pos}, 长度: ${result.length}`);
}

// 搜索并替换(所有Provider支持)
await sdk.searchAndReplace({ 
  old: '目标文本', 
  new: '新文本' 
});

// 根据文本定位(所有Provider支持)
await sdk.locateByText({ text: '目标文本' });

// 清除所有高亮(仅WPS支持)
if (sdk.getCurrentProviderType() === OfficeProviderType.WPS) {
  await sdk.clearHighlight();
}

文档格式化 / Document Formatting

// 格式化整个文档(仅WPS支持)
if (sdk.getCurrentProviderType() === OfficeProviderType.WPS) {
  await sdk.formatDocumentFont({
    name: '微软雅黑',
    size: 14,
    bold: false,
    italic: false,
    color: '#333333'
  });
}

// 设置文档为只读模式(所有Provider支持)
await sdk.setReadOnly(true);

内容控制 / Content Control

// 添加内容控制字段(所有Provider支持)
await sdk.addContentControl({
  fieldId: 'field-1',
  placeholderText: '请输入内容'
});

// 设置内容控制的值
await sdk.setContentControlValue('field-1', '字段内容');

// 设置内容控制高亮颜色 [R, G, B, A]
await sdk.setControlsHighlight([255, 0, 0, 1]); // 红色高亮

// 删除内容控制
await sdk.removeContentControl('field-1');

评论和视图操作 / Comments and View Operations

// 获取评论列表(所有Provider支持)
const comments = await sdk.getCommentsList('document-key');

// 跳转到指定评论
await sdk.jumpCommentDto('comment-id', 'document-key');

// 滚动到指定位置(所有Provider支持)
await sdk.viewScrollToY(500);

// 适应宽度(所有Provider支持)
await sdk.zoomFitToWidth();

修订管理 / Revision Management

// 获取所有修订
const revisions = await sdk.getRevisions();
console.log(`找到 ${revisions.length} 个修订`);

// 批量处理修订
const revisionIds = revisions.map(r => r.index);
await sdk.handleRevisions(revisionIds, 'accept'); // 或 'reject'

❓ 常见问题 / FAQ

Q: 如何确定使用哪种配置模式?

A: 推荐使用自动配置模式,它可以根据文档自动选择合适的 Provider。如果你需要精确控制或在离线环境中使用,可以选择手动配置模式。

Q: configApiUrl 的完整URL是什么?

A: SDK 会自动拼接完整路径。如果你传入 configApiUrl: 'https://api.example.com',实际请求的URL是: https://api.example.com/api/office/online-office/config?fileId=xxx&permissionToken=xxx

Q: 是否支持同时加载多个文档?

A: 是的,你可以使用 createOfficeSDK() 创建多个独立的 SDK 实例,每个实例管理一个文档。

Q: 哪些功能是WPS特有的?

A: WPS 特有的功能包括:insertTextAtCursorreplaceTexthighlightTextclearHighlightgetDocumentLengthformatDocumentFontgetRevisionshandleRevisionsacceptReviewByText。其他功能(如内容控制、评论、搜索等)所有Provider都支持。

Q: 如何处理大文档的性能问题?

A: SDK 内置了性能优化,包括懒加载、事件节流等。对于特别大的文档,建议使用只读模式或分页加载。

Q: 是否支持自定义 Provider?

A: 是的,你可以实现 IOfficeProvider 接口创建自定义 Provider,然后通过 OfficeProviderFactory 注册。

Q: 如何调试初始化问题?

A: 启用详细的错误回调,检查控制台输出。确保:

  • 容器元素存在且可见
  • configApiUrl 正确(会自动拼接 /api/office/online-office/config
  • token 和 permissionToken 有效(如果使用)
  • 网络连接正常

🤝 贡献指南 / Contributing

我们欢迎所有形式的贡献!请查看我们的贡献指南:

  1. Fork 项目
  2. 创建功能分支 (git checkout -b feature/AmazingFeature)
  3. 提交更改 (git commit -m 'Add some AmazingFeature')
  4. 推送到分支 (git push origin feature/AmazingFeature)
  5. 开启 Pull Request

📄 许可证 / License

MIT License - 查看 LICENSE 文件了解详情。


🔗 相关链接 / Related Links


📞 支持 / Support

如果你有任何问题或建议,请:


⭐ 如果这个项目对你有帮助,请给它一个 Star!

Made with ❤️ by [Your Team]