# OfficeCLI 技术方案分析 > 调研时间:2026 年 5 月 | 作者:沙洲工作室 > > 基于源码阅读(v1.0.72),非黑盒测评 ## 基本信息 | 项目 | 信息 | |------|------| | 仓库 | [iOfficeAI/OfficeCLI](https://github.com/iOfficeAI/OfficeCLI) | | 语言 | C#(.NET 10) | | 许可证 | Apache 2.0 | | 代码量 | ~285 个源文件,约 137,800 行 C# | | 外部依赖 | 仅 3 个 NuGet 包 | | 支持格式 | Word (.docx)、Excel (.xlsx)、PowerPoint (.pptx) | --- ## 一、整体架构 ### 分层结构 ``` ┌─────────────────────────────────────────────────────────┐ │ AI Agent / 用户终端 │ ├────────────┬──────────────┬─────────────────────────────┤ │ CLI 命令 │ MCP Server │ Resident 管道(Named Pipe) │ │ (System. │ (JSON-RPC │ (常驻进程,内存持有文档, │ │ CommandLine│ over stdio) │ 近零延迟响应) │ │ 路由) │ │ │ ├────────────┴──────────────┴─────────────────────────────┤ │ CommandBuilder │ │ (partial class,按功能拆分十余个文件) │ │ View / Set / Add / Get / Dump / Raw / Batch / │ │ Watch / Mark / Help / Import / Refresh / Check │ ├─────────────────────────────────────────────────────────┤ │ DocumentHandlerFactory │ │ (按扩展名分发到对应 Handler) │ ├──────────┬───────────────┬──────────────────────────────┤ │ WordHandler │ ExcelHandler │ PowerPointHandler │ │ (~25 partial│ (~20 partial │ (~30 partial files) │ │ files) │ files) │ │ │ 持有 │ 持有 │ 持有 │ │ Wordprocessing│Spreadsheet │ Presentation │ │ Document │ Document │ Document │ ├──────────┴───────────────┴──────────────────────────────┤ │ Core 模块 │ │ ┌──────────┬──────────┬──────────┬──────────────────┐ │ │ │ Formula/ │ Chart/ │ Watch/ │ PivotTableHelper │ │ │ │ 公式解析 │ SVG渲染 │ 实时预览 │ 透视表引擎 │ │ │ │ + 求值 │ + ChartEx│ + SSE │ │ │ │ ├──────────┼──────────┼──────────┼──────────────────┤ │ │ │ ThemeColor│ FontMetrics│ Units │ HtmlPreview │ │ │ │ 主题色解析│ 字体度量 │ 单位转换│ HTML 预览 │ │ │ └──────────┴──────────┴──────────┴──────────────────┘ │ ├─────────────────────────────────────────────────────────┤ │ DocumentFormat.OpenXML SDK 3.4.1 │ │ (微软开源 OpenXML SDK) │ └─────────────────────────────────────────────────────────┘ ``` ### 模块关系 **入口层**:`Program.cs` 是 top-level statements 入口。在进入 System.CommandLine 之前,先拦截处理一批"快捷命令"——`mcp`、`install`、`skills`、`load_skill`、`config` 等,这些不走标准 CLI 路由。 **命令路由层**:`CommandBuilder` 是一个 partial class,拆分到十几个文件(`CommandBuilder.View.cs`、`CommandBuilder.Set.cs`、`CommandBuilder.Add.cs` 等),通过 `BuildRootCommand()` 注册所有子命令。注册的命令包括:`open/close`、`view`、`get`、`query`、`set`、`add`、`remove`、`move`、`swap`、`raw`、`rawSet`、`addPart`、`validate`、`batch`、`dump`、`import`、`create`、`merge`、`watch/unwatch`、`mark/unmark`、`goto`、`help` 等。 **Handler 层**:`DocumentHandlerFactory.Open()` 根据文件扩展名分发到三个 Handler。每个 Handler 持有对应的 OpenXML Document 对象,用 partial class 按功能拆分为大量文件: | Handler | partial 文件数 | 覆盖功能 | |---------|--------------|---------| | WordHandler | ~25 | View/Set/Add/Query/Navigation/HtmlPreview/FormFields/StyleList/I18n/ImageHelpers/Selector | | ExcelHandler | ~20 | View/Set/Add/Query/Import/Slicer/HtmlPreview/CheckOverflow,带行索引缓存 | | PowerPointHandler | ~30 | View/Set/Add/Query/Fill/Effects/Animations/Background/Theme/Comments/Hyperlinks/SvgPreview/Model3D | **Core 层**:40+ 个辅助模块,包含多个自研引擎(公式、图表、透视表等),以及主题色解析、字体度量、单位转换、HTML 预览等基础能力。 **统一接口**:三个 Handler 都实现 `IDocumentHandler` 接口,这是整个项目的核心抽象。 --- ## 二、API / CLI 抽象设计 ### 三层操作架构 OfficeCLI 最核心的设计是将 Office 文档操作分为三个粒度层次: #### L1:语义视图层(只读,理解文档) | 命令 | 视图模式 | 用途 | |------|---------|------| | `view --mode text` | 纯文本 | 获取文档全部文字内容 | | `view --mode annotated` | 带编号标注 | 每个元素标上 `[P1]` `[T2]` 等编号,AI 通过编号定位 | | `view --mode outline` | 大纲 | 文档标题层级结构 | | `view --mode stats` | 统计 | 字数、段落数、表格数等 | | `view --mode issues` | 问题检测 | 格式问题、兼容性问题 | | `view --mode html` | HTML 预览 | 可视化渲染 | 所有视图模式都有 JSON 变体(如 `ViewAsStatsJson()`),支持 `--start/--end/--max-lines/--cols` 分页参数。 **`annotated` 视图是关键设计**——它为文档中的每个元素生成唯一编号,AI Agent 在后续的编辑操作中可以直接引用编号进行精确定位,不需要用模糊的自然语言描述位置。 #### L2:DOM 操作层(读写,结构化编辑) | 命令 | 功能 | 操作粒度 | |------|------|---------| | `get ` | 获取元素,返回 `DocumentNode` | 元素级,可指定深度 | | `query ` | CSS-like 选择器查询 | 类型/属性筛选 | | `set ` | 修改元素属性 | 属性级(字体、颜色、对齐等) | | `add ` | 添加元素 | 支持 Index/After/Before 定位 | | `remove ` | 删除元素 | 元素级 | | `move ` | 移动元素 | 元素级 | | `swap ` | 交换两个元素 | 元素级 | `DocumentNode` 是跨文档类型的**通用 DOM 节点抽象**,包含:path(DOM 路径)、type(元素类型)、text(文本内容)、preview(预览)、style、format(属性字典)、children(子节点)。 #### L3:Raw XML 层(底层逃生舱) | 命令 | 功能 | |------|------| | `raw ` | 直接读取 OpenXML part 的原始 XML | | `rawSet ` | XPath 定位并修改 XML 节点 | | `addPart` | 创建新的 XML part(图表、页眉页脚等) | | `validate` | OpenXML schema 合规性验证 | 这层的存在非常务实:Office 格式的 XML 规范极其庞大,L2 无法覆盖所有操作。当 AI Agent 遇到 L2 不支持的功能时,可以降级到 XML 层直接操作——相当于一个"逃生舱"。 ### AI Agent 交互设计 **1. MCP Server** `McpServer.cs` 实现了 JSON-RPC 2.0 over stdio 的 MCP 协议。为了兼容 .NET 的 PublishTrimmed(会裁剪掉反射),手写 `Utf8JsonWriter` 序列化,不使用 JSON 反射。支持 `tools/list` 和 `tools/call`,内置后台升级检查。 `McpInstaller` 支持一键注册到主流 AI 编辑器的配置文件:Claude Code、Cursor、VS Code Copilot、LM Studio。 **2. SKILL.md 技能系统** 内置 `SKILL.md` 文件嵌入到二进制中,AI Agent 读取后自动学会使用方式。策略分层指导 AI 先用 L1 理解文档,再用 L2 编辑,必要时降级 L3。 `skills/` 目录包含 12 个专项技能包: | 技能 | 场景 | |------|------| | officecli-docx / xlsx / pptx | 三种格式的通用操作指南 | | morph-ppt / morph-ppt-3d | PPT Morph 动画和 3D 效果 | | officecli-academic-paper | 学术论文模板 | | officecli-data-dashboard | 数据仪表板 | | officecli-financial-model | 财务模型 | | officecli-pitch-deck | 商业路演 PPT | | officecli-word-form | Word 表单 | 通过 `officecli skills install` 安装到 Agent 环境。 **3. Schema 驱动的帮助系统** `schemas/help/` 目录按格式(docx/pptx/xlsx)存放 JSON Schema 文件,描述每种元素的属性、别名、示例。嵌入为 EmbeddedResource,运行时通过 `SchemaHelpLoader` 读取,`SchemaHelpRenderer` 渲染。支持按动词(add/set/get)过滤——AI 可以查询"我能给 slide 设置哪些属性"。 **4. JSON 输出** 全局 `--json` 选项,`OutputFormatter.WrapEnvelopeText()` 统一 JSON 信封格式。所有命令的输出都可以结构化,方便 AI 解析。 --- ## 三、Office 文档引擎 ### 底层依赖:OpenXML SDK OfficeCLI 基于微软开源的 `DocumentFormat.OpenXml 3.4.1` 构建。这个 SDK 提供了 Office Open XML(OOXML)格式的底层读写能力——本质上是操作 .docx/.xlsx/.pptx 文件内部的 XML 结构。 OpenXML SDK 本身是**低层级**的——它只提供 XML 节点的创建和操作,不提供"添加一个格式化的表格"这样的高层 API。OfficeCLI 在此基础上自研了大量高层抽象。 ### 自研引擎模块 **1. 公式引擎(Core/Formula/)** 自研 Excel 公式解析和求值器: - `FormulaParser.cs` — 将公式文本解析为 AST - `FormulaEvaluator.cs` + `.Functions.cs` + `.Helpers.cs` — 150+ 内置函数的求值 - 支持 Numeric/String/Boolean/Error/Array 类型 - 15 位有效数字精度控制 - `ModernFunctionQualifier` 处理新版函数名 这意味着 OfficeCLI 可以在不打开 Excel 的情况下**计算公式结果**。 **2. 图表引擎(Core/Chart/)** 这是代码量最大的自研模块之一: - `ChartSvgRenderer.cs`(2,897 行)— 完整的 SVG 图表渲染器 - `ChartSvgRenderer.CxExtract.cs` — ChartEx 扩展图表支持(直方图、漏斗图、树状图、旭日图、箱线图) - `ChartHelper.cs` + Builder/Reader/Setter/Axis/Advanced — 图表 DOM 操作 - `ChartExBuilder.cs` — ChartEx 格式构建器 - `ChartPresets.cs` / `ChartExResources.cs` — 预设样式和嵌入的 XML 模板 可以在不安装 Office 的情况下**渲染图表为 SVG**。 **3. 透视表引擎(Core/PivotTableHelper\*)** 6 个 partial 文件覆盖完整的透视表处理链:Parse → Cache → Definition → Render → Set → Readback。自行实现了透视表的缓存计算。 **4. 主题色系统** - `ThemeColorResolver` — 解析 Office 主题色(accent1-6 + shade/tint 变体) - `OfficeDefaultThemeColors` — 内置默认主题 - 这是正确渲染 Office 文档颜色的关键——Office 的颜色系统不是简单的 hex,而是基于主题的相对值 **5. 其他自研模块** | 模块 | 功能 | |------|------| | FontMetricsReader / LocaleFontRegistry | 字体度量和区域字体映射 | | WordTocBuilder | 目录自动构建 | | WordNumFmtRenderer | Word 编号格式渲染 | | ExcelStyleManager | Excel 样式管理 | | HtmlPreviewHelper / HtmlScreenshot | HTML 预览和浏览器截图 | | DrawingEffectsHelper | 绘图效果(阴影、发光等) | | SvgImageHelper | SVG 图片处理 | | EmuConverter / Units / SpacingConverter | EMU/pt/cm/inch 单位转换 | | OleHelper + OpenMcdf | OLE 嵌入对象处理 | | WordStrictAttributeSanitizer | Strict OpenXML 属性清理 | | GenericXmlQuery | 通用 XML 查询 | | TemplateMerger | 模板合并 | | PathAliases | DOM 路径别名系统 | ### 兼容性考量 **优势**: - 基于 OpenXML SDK,直接操作标准 OOXML 格式,与 Microsoft Office 原生兼容 - 支持 Strict OpenXML 和 Transitional OpenXML 两种变体 - 完整的 i18n 和 RTL(从右到左文字)支持 - `validate` 命令可验证文档是否符合 OpenXML schema **风险**: - OpenXML SDK 只是"能读写 XML",正确性取决于上层实现——Office 格式有大量未文档化的行为和边缘情况 - 不支持旧格式(.doc/.xls/.ppt),仅支持 OOXML 格式(.docx/.xlsx/.pptx) - 图表渲染、公式求值等自研引擎可能与 Office 的实际行为有差异 - **没有自动化测试**(13.8 万行代码零测试),格式兼容性靠人工验证 --- ## 四、技术栈 | 组件 | 技术选择 | 说明 | |------|---------|------| | 运行时 | .NET 10.0 | 最新版,启用 nullable + implicit usings | | CLI 框架 | System.CommandLine 3.0.0-preview | 微软官方 CLI 库(仍是预览版) | | 文档引擎 | DocumentFormat.OpenXml 3.4.1 | 微软开源 OpenXML SDK | | OLE 支持 | OpenMcdf 3.1.3 | 开源 OLE 复合文档库 | | IPC | Named Pipe | 驻留模式进程间通信 | | MCP | 手写 JSON-RPC 2.0 | 不依赖 MCP 框架库 | | 序列化 | Utf8JsonWriter + Source Generator | 兼容 PublishTrimmed,避免反射 | | 构建 | dotnet publish | PublishSingleFile + SelfContained + PublishTrimmed | | 实时预览 | 内嵌 HTTP 服务器 + SSE | Watch Mode | | CI/CD | GitHub Actions | 8 个平台目标交叉编译 | ### 单二进制分发 通过 .NET 的三个发布选项组合实现: - `PublishSingleFile` — 打包为单文件 - `SelfContained` — 内嵌 .NET 运行时 - `PublishTrimmed` — 裁剪未使用的代码 Skills、Schemas、CSS/JS 资源全部作为 `EmbeddedResource` 嵌入程序集。`build.sh` 支持 8 个平台目标:macOS (ARM64/x64)、Linux (x64/ARM64/musl)、Windows (x64/ARM64)。macOS 构建包含 ad-hoc 代码签名。 ### 驻留模式(Resident Mode) **问题**:每次执行 CLI 命令都要启动 .NET 运行时 → 打开文件 → 解析 XML → 执行操作 → 保存文件。AI Agent 连续执行几十条命令时,这个开销不可接受。 **解法**:双管道架构的常驻进程: - **主命令管道**:接收和执行命令 - **Ping 管道**:独立的健康检查通道,用于验证进程是否存活 - `SemaphoreSlim` 单命令锁,串行化请求 - 两种生命周期:自动启动模式(60 秒空闲退出),显式 open/close 模式(12 分钟空闲退出) - 支持 `__set-idle-timeout__` RPC 动态调整超时 - 关键不变量:ping 响应 ⇔ handler 持有文件锁 **流程**:`open` → 启动子进程(`__resident-serve__`)→ 后续命令通过 pipe 转发 → `close` 发送关闭指令。Windows 上有特殊处理来避免 handle 继承泄漏。