# yx_only_office_flutter 面向 Flutter 项目的 ONLYOFFICE 文档查看与编辑插件。基于 `webview_flutter` 实现,完全遵循 [ONLYOFFICE Docs API](https://api.onlyoffice.com/docs/docs-api/get-started/basic-concepts/) 官方规范。 ## 官方参考 - [ONLYOFFICE Docs API - Basic Concepts](https://api.onlyoffice.com/docs/docs-api/get-started/basic-concepts/) - [ONLYOFFICE Documents App for Android](https://github.com/ONLYOFFICE/documents-app-android) - [ONLYOFFICE Documents App for iOS](https://github.com/ONLYOFFICE/documents-app-ios) ## 功能特性 ### 基础功能 - ✅ **完整的查看与编辑支持**:支持 `view` 和 `edit` 两种模式 - ✅ **标准配置结构**:完全遵循官方 DocsAPI 配置规范 - ✅ **丰富的事件桥接**:支持 `onError`、`onAppClose`、`onDownloadAs`、`onRequestSaveAs`、`onRequestInsertImage`、`onDocumentStateChange` 等事件 - ✅ **JWT 签名支持**:内置 HMAC-SHA256 JWT 签名工具 - ✅ **高度可定制**:支持自定义 UI、权限、语言、用户信息等 - ✅ **跨平台支持**:同时支持 Android 和 iOS ### 高级功能 🚀 NEW - ✅ **WebViewController 直接访问**:完全控制底层 WebView - ✅ **编辑器方法调用**:直接调用 DocsAPI 方法(插入图片、下载、审阅等) - ✅ **图片插入**:从相机/相册插入图片到文档 - ✅ **文件下载处理**:自动拦截和处理文件下载 - ✅ **生命周期管理**:完整的编辑器生命周期事件 - ✅ **自定义 JavaScript**:执行任意 JS 代码 查看 [高级功能指南](docs/ADVANCED_FEATURES.md) 了解详情。 ## 环境要求 1. 可访问的 ONLYOFFICE Document Server(云端或自建) 2. 能够提供可下载的文件地址(HTTP/HTTPS) 3. Flutter 3.3+,Dart 3.9.2+ ## 安装 ```yaml dependencies: yx_only_office_flutter: ^0.1.0 ``` 或使用命令: ```sh flutter pub add yx_only_office_flutter ``` ## 快速开始 > 💡 **提示**: 对于高级功能(图片插入、文件下载、编辑器方法调用等),请查看 [高级功能指南](docs/ADVANCED_FEATURES.md) ### 1. 查看文档(只读模式) ```dart import 'package:flutter/material.dart'; import 'package:yx_only_office_flutter/yx_only_office_flutter.dart'; class DocumentViewerPage extends StatelessWidget { const DocumentViewerPage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('文档查看')), body: YxOnlyOfficeViewer.create( serverUrl: 'https://your-onlyoffice-server.com', fileUrl: 'https://example.com/document.docx', mode: 'view', // 只读模式 title: '示例文档.docx', allowDownload: true, allowPrint: false, user: const OnlyOfficeUser( id: 'user123', name: '张三', ), onError: (error) { debugPrint('文档加载错误: $error'); }, ), ); } } ``` ### 2. 编辑文档 ```dart YxOnlyOfficeViewer.create( serverUrl: 'https://your-onlyoffice-server.com', fileUrl: 'https://example.com/document.docx', mode: 'edit', // 编辑模式 title: '可编辑文档.docx', user: const OnlyOfficeUser( id: 'user123', name: '张三', email: 'zhangsan@example.com', ), onDocumentStateChange: (data) { // 文档状态变化(是否有未保存的修改) final isModified = data ?? false; debugPrint('文档已修改: $isModified'); }, onRequestSaveAs: (data) { // 用户点击"另存为" debugPrint('请求保存: $data'); }, onRequestInsertImage: (data) { // 用户请求插入图片(可以打开 Flutter 图片选择器) debugPrint('请求插入图片: $data'); }, ) ``` ### 3. 使用 JWT 签名(推荐用于生产环境) ```dart const jwtSecret = String.fromEnvironment('ONLYOFFICE_JWT_SECRET'); YxOnlyOfficeViewer.create( serverUrl: 'https://your-onlyoffice-server.com', fileUrl: 'https://example.com/document.docx', mode: 'edit', tokenFactory: jwtSecret.isNotEmpty ? OnlyOfficeJwtSigner(jwtSecret) : null, onError: (error) => debugPrint('错误: $error'), ) ``` ### 4. 高级配置(手动构建配置) ```dart final config = OnlyOfficeConfigFactory.create( fileUrl: 'https://example.com/document.docx', mode: 'edit', title: '高级配置文档.docx', lang: 'zh-CN', user: const OnlyOfficeUser( id: 'user123', name: '张三', email: 'zhangsan@example.com', ), customization: const OnlyOfficeCustomization( compactToolbar: true, hideRightMenu: false, toolbarNoTabs: false, ), tokenFactory: OnlyOfficeJwtSigner('your-secret-key'), ); YxOnlyOfficeViewer( serverUrl: 'https://your-onlyoffice-server.com', config: config, onEvent: (event, data) { // 通用事件处理器,捕获所有事件 debugPrint('事件: $event, 数据: $data'); }, ) ``` ## 支持的文档格式 插件自动识别以下文档类型: ### 文字处理 (word) `doc`, `docx`, `docm`, `dot`, `dotx`, `dotm`, `odt`, `fodt`, `ott`, `rtf`, `txt`, `html`, `htm`, `mht`, `xml`, `pdf`, `djvu`, `fb2`, `epub`, `xps` ### 电子表格 (cell) `xls`, `xlsx`, `xlsm`, `xlt`, `xltx`, `xltm`, `ods`, `fods`, `ots`, `csv` ### 演示文稿 (slide) `ppt`, `pptx`, `pptm`, `pps`, `ppsx`, `ppsm`, `pot`, `potx`, `potm`, `odp`, `fodp`, `otp` ## 事件回调说明 | 事件 | 说明 | 回调参数 | |------|------|----------| | `onError` | 文档加载或编辑错误 | `String error` | | `onAppClose` | 用户请求关闭编辑器 | 无 | | `onDownloadAs` | 文档下载完成 | `String fileType, String url` | | `onRequestSaveAs` | 用户点击"另存为" | `dynamic data` | | `onRequestInsertImage` | 用户请求插入图片 | `dynamic data` | | `onDocumentStateChange` | 文档修改状态变化 | `dynamic data` (boolean) | | `onMetaChange` | 文档元数据变化 | `dynamic data` | | `onMakeActionLink` | 创建操作链接 | `dynamic data` | | `onEvent` | 通用事件处理器 | `String event, dynamic data` | ## 配置类说明 ### OnlyOfficeConfig 顶层配置对象,包含: - `document`: 文档元数据(`OnlyOfficeDocument`) - `documentType`: 文档类型(`word`/`cell`/`slide`) - `editorConfig`: 编辑器配置(`OnlyOfficeEditorConfig`) - `type`: 客户端类型(默认 `mobile`) - `token`: JWT 令牌(可选) ### OnlyOfficeDocument 文档信息: - `fileType`: 文件扩展名(如 `docx`) - `key`: 文档唯一标识(自动生成或手动指定) - `title`: 文档标题 - `url`: 文档下载地址 - `permissions`: 文档权限(`OnlyOfficePermissions`) ### OnlyOfficeEditorConfig 编辑器设置: - `mode`: 模式(`view` 或 `edit`) - `lang`: 界面语言(默认 `zh-CN`) - `user`: 用户信息(`OnlyOfficeUser`) - `customization`: UI 自定义(`OnlyOfficeCustomization`) - `callbackUrl`: 回调地址(可选,用于服务端保存) ### OnlyOfficePermissions 权限控制: - `edit`: 是否允许编辑 - `download`: 是否允许下载 - `print`: 是否允许打印 - `review`: 是否允许审阅 - `comment`: 是否允许评论 - `copy`: 是否允许复制 - `fillForms`: 是否允许填写表单 ### OnlyOfficeCustomization UI 定制: - `compactToolbar`: 紧凑工具栏 - `hideRightMenu`: 隐藏右侧菜单 - `hideLeftMenu`: 隐藏左侧菜单 - `hideRulers`: 隐藏标尺 - `toolbarNoTabs`: 工具栏无标签页 - `showReviewChanges`: 显示审阅更改 ## JWT 签名 ### ⚠️ 重要更新:OnlyOffice Docs 7.1+ 身份验证 从 OnlyOffice Docs 7.1 版本开始,当服务器启用 JWT 验证时,**必须使用 JWT Secret 对整个配置进行签名**。 **正确用法**(传入 JWT Secret,而非预生成的 Token): ```dart OnlyOfficeViewer( onlyOfficeServerUrl: 'https://your-onlyoffice-server.com', fileUrl: 'https://example.com/document.docx', jwtSecret: 'your-jwt-secret-key', // ✅ 传入 secret,插件会自动签名 ) ``` 插件会自动使用 HMAC-SHA256 算法对整个配置进行签名,并将生成的 token 添加到配置中。 **错误用法**(旧版本的做法,在 7.1+ 会报错): ```dart // ❌ 不要这样做! OnlyOfficeViewer( onlyOfficeServerUrl: 'https://your-onlyoffice-server.com', fileUrl: 'https://example.com/document.docx', token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...', // ❌ 错误 ) ``` **安全提示**: - ⚠️ 不要在客户端硬编码 JWT 密钥 - ✅ 推荐通过环境变量或服务端 API 获取签名 - ✅ 生产环境应在服务端完成签名 - 📖 参考:[JWT 修复指南](JWT_FIX_GUIDE.md) 和 [ONLYOFFICE 官方文档](https://api.onlyoffice.com/docs/docs-api/additional-api/signature/) ## 示例工程 查看 `example/` 目录获取完整示例,包括: - 基础查看功能 - 编辑模式演示 - JWT 签名集成 - 事件处理示例 - 集成测试 运行示例: ```sh cd example flutter run \ --dart-define ONLYOFFICE_SERVER_URL=https://your-server.com \ --dart-define ONLYOFFICE_FILE_URL=https://example.com/doc.docx \ --dart-define ONLYOFFICE_JWT_SECRET=your-secret ``` ## 常见问题 ### 1. 文档无法加载?DocsAPI is not loaded 错误? **这是最常见的问题!** 通常是因为: - ❌ **使用了示例 URL** (`https://doc.example.com/`) - 这不是真实服务器 - ❌ **服务器 URL 不正确** - 无法访问 ONLYOFFICE Document Server - ❌ **网络连接问题** - 无法连接到服务器 - ❌ **CORS 未启用** - 服务器未配置跨域访问 - ❌ **权限配置缺失** - Android/iOS 未配置网络权限 ⚠️ **最常见** **解决方案**: 1. **首先检查权限配置** - 查看 [权限和网络配置指南](docs/PERMISSIONS_AND_NETWORK_CONFIG.md) ⚠️ **重要** 2. 确保使用**真实的** ONLYOFFICE Document Server 地址 3. 在浏览器中测试 API 脚本 URL: `https://your-server.com/web-apps/apps/api/documents/api.js` 4. 检查网络连接和防火墙设置 5. 查看 [故障排除指南](docs/TROUBLESHOOTING.md) 获取详细帮助 **快速修复权限问题**: - Android: 确保 `AndroidManifest.xml` 包含 `INTERNET` 权限和 `network_security_config` - iOS: 确保 `Info.plist` 包含 `NSAppTransportSecurity` 配置 - 配置后执行 `flutter clean` 并重新构建 **快速检查**: ```bash # 在浏览器中打开这个 URL,应该能看到 JavaScript 代码 https://your-server.com/web-apps/apps/api/documents/api.js ``` ### 2. 其他常见问题 检查: - Document Server 是否可访问 - 文件 URL 是否可下载 - JWT 签名是否正确(如果启用) - 网络权限是否配置(Android/iOS) ### 2. 编辑模式不生效? 确保: - `mode` 设置为 `'edit'` - `document.permissions.edit` 为 `true` - 用户信息已正确配置 ### 3. 如何保存编辑后的文档? ONLYOFFICE 支持两种保存方式: 1. **服务端回调**:配置 `callbackUrl`,Document Server 会将修改推送到你的服务器 2. **客户端下载**:监听 `onDownloadAs` 事件,获取修改后的文档 URL ## 兼容性 - ✅ Android 5.0+ - ✅ iOS 11.0+ - ✅ ONLYOFFICE Document Server 6.1+ ## 许可证 本项目采用 MIT 许可证,详见 [LICENSE](LICENSE) 文件。 ## 贡献 欢迎提交 Issue 和 Pull Request! ## 更新日志 查看 [CHANGELOG.md](CHANGELOG.md) 了解版本更新历史。