金山文档技能 JSAPI 执行引擎深度解析
一、架构全景:分层命令透传体系
金山文档技能的 JSAPI 执行引擎并非传统意义上的"脚本运行器",而是一套分文档类型、分抽象层级的结构化命令透传系统。CLI 工具接收参数,经 Service 路由分发到在线编辑器内核,最终由 JSAPI Engine 对文档对象模型执行原子操作。调用方不需要理解文档的内部存储格式,只需按约定的命令协议下发 JSON 指令即可完成操控。
引擎 | 文档类型 | 抽象层级 | 操作粒度 |
wpp.execute | .pptx | 预定义命令模板 | 幻灯片与形状级 |
wps.core_execute | .docx | 预定义命令模板 | 段落与字符级 |
otl.* | .otl | ProseMirror 节点树 | 文档块级 |
sheet.* | .xlsx / .ksheet | 单元格选区 | 行列与单元格级 |
dbsheet.* | .dbt | 关系数据模型 | 记录与字段级 |
所有操作均通过结构化 JSON 指令下发,禁止传入任意 JavaScript,返回格式统一为包含状态码和消息的 JSON 对象。区别在于各自对文档模型的理解方式和操作抽象的层级——wpp.execute 和 wps.core_execute 采用预注册命令模式,每条命令有固定参数签名;otl.* 直接操作文档节点树,自由度最高;sheet.* 基于矩形选区进行批量读写;dbsheet.* 以关系数据模型管理结构化信息。
二、wpp.execute — 演示文稿原子命令引擎
wpp.execute 是典型的命令路由型引擎,将演示文稿操作抽象为离散的原子命令,每条命令对应固定参数签名和返回结构。
幻灯片操作
提供四个命令,采用 1-based 索引(与 WPP 内核一致):addLayoutSlide 在指定位置插入特定版式的幻灯片,deleteSlide 删除指定页,copyPasteSlide 复制并粘贴到目标位置(不传目标则默认追加末尾),getSlidesCount 返回总页数。其中 addLayoutSlide 支持 12 种版式枚举,从标题幻灯片、标题和文本、两栏文本到表格和图表等复合版式,再到仅标题和空白页。合理选择版式可以减少后续形状和文本框的插入工作量。值得注意的是,addLayoutSlide 插入的是预格式化的空白幻灯片,文本和图形内容需通过其他命令或工具单独填充。
形状操作
形状类命令共享统一参数——幻灯片序号 slideIndex、坐标 left/top、尺寸 width/height,单位为磅(Point),与 WPS 桌面端保持一致。当前注册了 addRectangle、addOval、addTriangle、addRoundedRectangle 四种基本形状。底层 AddShape 签名实际支持 15 种以上类型(菱形、平行四边形、五角星、箭头等),当前文档中已列出完整清单,为后续扩展预留了空间。形状插入后默认无填充、无文本,需配合其他命令设置样式。
与非 JSAPI 工具的协作
wpp.execute 并非唯一操作入口。同服务下 wpp.insert_slide 使用 0-based 索引,wpp.set_font_presentation 和 wpp.set_color_presentation 负责全文级字体与配色切换,wpp.export_image 和 wpp.export_pdf 处理导出(后者为异步任务,需轮询状态)。wpp.execute 的优势在于原子性和精确控制——每条命令只做一件事,适合逐步构建幻灯片结构的复杂场景。
三、wps.core_execute — 文字文档模块化命令引擎
模块化架构
wps.core_execute 规划了 19 个功能模块,涵盖文档内容、段落格式、字符格式、样式、表格、图片、书签、目录、页眉页脚、批注、脚注、控件、超链接、列表、节设置、形状、修订、域和水印。当前已上线前三个模块共 23 条命令,覆盖日常文档编辑最核心的操作。模块化设计使得后续新能力的上线不影响已有命令行为。
双定位模式
模块一(文档内容)和模块二(段落格式)共享"双定位"设计——段落定位以 n 指定段落序号(1-based),命令前缀 modifyParagraph*;区间定位以 begin/end 指定字符区间(0-based,左闭右开),命令前缀 modifyRange*。两者成对出现,覆盖内容读写、对齐、缩进、行间距、字体样式和高亮色等相同的能力集。按语义段落修改时用段落定位更直观,精确到特定字符范围时用区间定位更灵活,两者也可配合——先用段落定位确定大致范围,再用区间定位做精细化调整。
Key-Value 属性模式
字符格式模块通过 key 选择属性维度,value 传入对应值。当前支持六个 key:Name(字体名称)、Size(磅值字号)、Bold(布尔值)、Italic(布尔值)、ColorIndex(16 种预设色,从黑色到 25% 灰色)、Underline(18 种样式,值从 0 到 55,涵盖单线、双线、点线、波浪线及其粗体变体)。关键约束:设置多个字符属性需分多次调用,每次只传一个 key-value。例如让第一段变为黑体加粗 18 磅,需依次执行三次 modifyParagraphFontStyle。这是因为在模块设计中每次调用只修改一个维度的样式,避免部分修改导致其他属性被意外覆盖。
枚举体系
该引擎建立了兼容 WPS 桌面端 VBA 的枚举体系。对齐方式 9 种模式,除基本的左对齐、居中、右对齐和两端对齐外,还包括分散对齐和三种不同字符压缩程度的变体。行间距 6 种规则:单倍、1.5 倍、双倍以及最小值、固定值和多倍行距(后三者需配合磅值参数)。这套枚举确保了服务端操作与桌面端在视觉效果上的一致性。文档还明确建议"先修改内容再设置格式",因为内容修改可能引起段落结构变化,先设格式后改内容会导致格式绑定因索引偏移而失效。
四、otl.* — 智能文档块操作引擎
从命令路由到节点树操作
otl.* 系列与前两套引擎的区别在于:它不依赖预定义命令,而是直接操作文档的 ProseMirror 节点树,通过 JSON 结构描述要操作的节点内容,操作自由度显著更高。提供五个工具:otl.insert_content 将 Markdown 追加到文档开头或末尾,otl.block_query 查询指定块结构,otl.block_insert 在精确位置插入节点,otl.block_update 更新块内容或属性,otl.block_delete 按索引区间删除块。
双层操作粒度
第一层是 Markdown 流式写入。otl.insert_content 接收 CommonMark 子集格式文本,系统自动转为富文本节点。但它仅支持追加操作(begin 或 end),不支持替换已有内容,也不接受原生 HTML 和 Mermaid 等自定义渲染语法。适合快速生成初始内容。
第二层是节点精确操作。节点分三类:IInline 行内节点(text、emoji、br、latex、linkView 等 9 种)、IBlock 块级节点(title、paragraph、heading、codeBlock、table、column、picture 等 19 种)及全局唯一的 doc 根节点。索引规则有两个要点:doc 块的 index=0 固定为 title 节点,正文从 index>=1 开始;rangeMarkBegin 和 rangeMarkEnd 是虚拟标记节点,计算索引时必须忽略,否则会导致偏移错误。每个节点有特定的可容纳子节点规则——例如 paragraph 可包含任意行内节点,而 codeBlock 的内容只能是纯文本。
block_update 的批处理
block_update 支持一次调用中执行多类操作:update_content 覆盖内容、update_attrs 更新属性、插入和删除行列、合并和拆分单元格。批量能力使复杂编辑可单次完成,减少网络往返。注意 update_attrs 是覆盖操作——只修改背景色时必须把原有属性一并传入,否则未包含的属性会被清除。因此更新前应先通过 block_query 获取属性快照。
五、sheet.* — 表格选区操作引擎
矩形选区模型
sheet.* 采用矩形选区模型,所有操作基于 (rowFrom, rowTo, colFrom, colTo) 四元组定义的区域,索引全部为 0-based。这个模型与 Excel 选区概念一致,支持对任意矩形区域进行批量读写。
多类型操作
sheet.update_range_data 通过 opType 在同一选区内执行不同操作:formula 写入值或公式(等号开头识别为公式,否则作为纯文本值),format 设置包含字体、对齐、边框、填充的完整格式对象 xf,字体部分支持名称、大小、颜色、加粗、斜体、删除线和下划线;merge 支持居中、跨越和普通三种合并方式;picture 通过 URL 写入图片到指定区域。xf 格式对象是表格引擎中最复杂的参数结构,覆盖了 Excel 单元格格式的全部维度。
读取能力
sheet.get_range_data 返回每个单元格七个维度:显示文本 cellText(格式化后的值)、原始值 originalCellValue、数字格式 numFormat、是否为图片 isCellPic、公式文本 fmlaText 及坐标。这种多维度的返回结构使调用方可根据业务逻辑灵活选择不同形式的值。sheet.get_sheets_info 提供工作表级元信息,其中 rowTo / colTo 表示实际数据区域边界,比理论最大值更实用,可据此设计分批读取策略。
六、dbsheet.* — 多维表格 CRUD 引擎
关系数据模型
dbsheet.* 是唯一采用关系数据模型的引擎。它不操作文档的视觉结构,而是操作抽象的数据实体,围绕数据表、记录、字段和视图四个维度提供完整 CRUD 能力。这种设计将文档从"内容展示"抽象为"数据容器",使项目管理、数据收集、库存管理等结构化场景脱离传统文档束缚。
Schema 驱动与高级查询
get_schema 是信息中枢,一次调用获取全部数据表、字段定义、视图配置和记录数量,后续所有操作都依赖 Schema 返回的 ID 进行定位。这种先查询后操作的模式确保了调用的准确性,不会因 ID 猜测错误导致操作失败。list_records 支持分页遍历和多字段 AND/OR 组合筛选,操作符涵盖等值、包含、空值判断、日期和数值比较等十余种。视图类型覆盖表格、看板、画册、表单、甘特和日历六种,每种视图对同一份数据提供不同可视化视角。字段类型涵盖文本、数值、日期、单选多选、附件、关联字段和公式字段,满足结构化数据管理的各类需求。
七、安全机制与风险控制
整套引擎体系建立了三级风险控制,确保操作的可控性与可追溯性。
引擎级:wpp.execute 和 wps.core_execute 只能调用已注册命令,禁止传入任意脚本;otl.insert_content 限制为 CommonMark 子集,不允许注入 HTML 或脚本标签;所有操作均返回包含 ok、message、data 三字段的统一 JSON 结构,便于调用方判断结果并采取后续动作。
操作级:写操作按风险分级。高风险操作(块删除、数据表删除、字段删除、批量记录删除等不可逆操作)要求执行前先查询确认目标存在性,避免误删。中风险操作(内容写入、覆盖更新等)要求前置检查加后置验证——写入前确认文档状态,写入后读取验证结果是否符合预期。
错误处理:特定错误码有禁止重试规则。InvalidArgument 表示 Markdown 内容非法,须重构内容而非原样重试,否则陷入死循环。InvalidFileKind 表示 file_id 与工具类型不匹配,应切换到对应引擎。这些规则防止错误在自动化场景中因盲目重试而被放大,从根本上保障了数据安全。