HarmonyOS WPS Open SDK:enableEdit 只读与可编辑打开模式

HarmonyOS 工程接入 @wps/wps_sdk 后,本地 Word / Excel / PPT 都走 OpenFileRequest 加 WPSApi.sendRequest。同一条打开链路里,是否允许用户改文档只由一个可选布尔字段决定:enableEdit。未赋值或写 false 时客户端以只读(ReadOnly)打开;只有显式写成 true 才进入可编辑(Normal)。联调里常见两类误判:预览按钮误传 true,以及编辑入口忘了赋值却以为「默认能改」。本文按接口语义写清模式分支、可复用封装与联调清单。字段以官方对接文档为准。

一、打开模式在调用链中的位置

固定顺序:HAR 集成 → registerApp 回调到 ResultCode.OK → 按凭据约定可选注入激活序列号 → 文件进入本应用沙箱 → new OpenFileRequest(context, path) → 设置 enableEdit → sendRequest。模式开关挂在 Request 上,不单独成类,也不改变 requestType:仍是 OPEN_FILE。

层级 职责 入口
门禁 注册成功才允许打开 registerApp / ResultCode.OK
路径 选择器 URI 拷进沙箱 filesDir 拷贝
模式 只读或可编辑 enableEdit
调度 拉起 WPS 并返回 Result WPSApi.sendRequest

水印、extraOptions、关窗回传是同一 Request 上的附加策略。模式未稳定前,不要把它们和 enableEdit 绑在同一个匿名点击回调里同时改,否则 ResultCode.ERROR 难以归因。

二、enableEdit 语义与对照

赋值 打开模式 说明
未设置 ReadOnly 默认只读,可预览不可改
false ReadOnly 与未设置同级
true Normal 仅该赋值进入可编辑

只有写成 true 这一支才会打开可编辑;未设与 false 都保持只读。enableEdit 与 wpsTransferType / enableTransferFile 独立:未开回传时,ResultCode.OK 且 data == null 表示拉起成功,不代表「已保存」。可编辑打开后若未开回传,关窗结果仍可能为空 data,UI 文案应写「已打开 WPS」,不要写「已同步到服务器」。

构造签名不变:

typescript 复制代码
new OpenFileRequest(context: UIAbilityContext, fileUri: string)

context 必须来自当前 UIAbility。fileUri 实践上应是本应用沙箱内路径;系统选择器外部 URI 常因权限不足打不开,日志却不一定含「权限」二字。

三、注册门禁与沙箱路径

模式实验建立在注册成功之上。未到 ResultCode.OK 就 sendRequest 会抛异常,该异常不是带 code 的打开 Result。1013(ERROR_CODE_AUTH_FAILURE)出现在注册阶段时,停止改 enableEdit,先对齐 bundleName、appKey / appSecret 与 HAR。

typescript 复制代码
import { WPSApi, Result, ResultCode } from '@wps/wps_sdk';

let ready = false;

export function bootstrap(appKey: string, appSecret: string, sn?: string): void {
  WPSApi.registerApp(appKey, appSecret, {
    onCallback: (r: Result): void => {
      if (r.code === ResultCode.ERROR_CODE_AUTH_FAILURE) {
        console.error('[WPS] 1013', r.msg ?? '');
        return;
      }
      if (r.code !== ResultCode.OK) {
        console.error('[WPS] register', r.code, r.msg ?? '');
        return;
      }
      if (sn) {
        WPSApi.setWpsFileToken(sn);
      }
      ready = true;
    },
  });
}

export function isReady(): boolean {
  return ready;
}

需要序列号时在注册成功回调里全局注入,不要写 OpenFileRequest.wpsToken。Release 禁止打印完整 appSecret。打开按钮在 ready 前保持禁用。

typescript 复制代码
import { common } from '@kit.AbilityKit';
import fs from '@ohos.file.fs';

export function copyInbox(
  ctx: common.UIAbilityContext,
  src: string,
  suffix: string
): string {
  const dir = `${ctx.filesDir}/wps_inbox`;
  fs.mkdirSync(dir, true);
  const dest = `${dir}/${Date.now()}.${suffix}`;
  fs.copyFileSync(src, dest);
  return dest;
}

拷贝失败不要继续 sendRequest。扩展名与真实类型保持一致。

四、预览与编辑共用封装

页面上不要出现两套 new OpenFileRequest。用第四个布尔参数区分模式:

typescript 复制代码
import { common } from '@kit.AbilityKit';
import {
  WPSApi,
  OpenFileRequest,
  Result,
  ResultCode,
} from '@wps/wps_sdk';

export async function openLocal(
  ctx: common.UIAbilityContext,
  src: string,
  suffix: string,
  editable: boolean
): Promise<Result> {
  if (!isReady()) {
    throw new Error('WPS not registered');
  }
  const path = copyInbox(ctx, src, suffix);
  const req = new OpenFileRequest(ctx, path);
  req.enableEdit = editable;
  return WPSApi.sendRequest(req);
}

export function interpretOpen(r: Result): void {
  if (r.code !== ResultCode.OK) {
    console.error('[WPS] open', r.code, r.msg ?? '');
    return;
  }
  if (!r.data) {
    console.info('[WPS] launched, transfer off or empty data');
    return;
  }
  console.info('[WPS] transfer payload present');
}

预览入口传 false 或保持默认:await openLocal(ctx, src, 'docx', false)。编辑入口必须传 true。.then 处理 Result.code;.catch 处理未注册异常。不要用一个 if (result) 覆盖两种形态。

组件侧在 UIAbility.onCreate 调 bootstrap,页面 aboutToAppear 只读 isReady(),点击里调用 openLocal 再 interpretOpen。列表多附件时循环只调封装,禁止每项内联构造 Request。

五、与回传、策略字段的边界

enableEdit = true 只解决「能不能改」。关窗后要拿业务 filePath,还须单独设置 wpsTransferType(或兼容字段 enableTransferFile),并把 WPS 沙箱路径拷回本应用后再入库。模式联调阶段建议:注册 OK → 沙箱只读 → 沙箱可编辑 → 再开回传。不要在同一周同时改 Inbox 目录名、Token 分支和 enableEdit 默认值。

extraOptions、水印属于打开层之上的策略,等只读与可编辑都稳定后再叠。换 HAR 批次后:ohpm install、clean,重跑注册与只读打开,再恢复可编辑与回传。

六、联调清单与工程落地

  1. 冷启动日志出现注册 code=0
  2. 预览入口界面只读,未误传 true
  3. 编辑入口传 true,可改内容
  4. 选择器文件经 copyInbox 再打开
  5. 未注册点击走 .catch,不伪造 Result
  6. 1013 时停止改模式开关
  7. 全仓搜索 new OpenFileRequest 只落在打开封装
  8. 全仓无 req.wpsToken =

调试包与商店包 bundleName 不同则凭据分开申请。远程缺陷单固定列:HAR 文件名、Bundle、注册 code/msg、打开 code/msg、本次 enableEdit 取值。五列齐了再讨论选择器 URI。

把模式相关约定写进模块边界:WpsBootstrap 只负责注册与就绪态;WpsInbox 只负责拷贝;WpsOpen 只导出 openLocal(ctx, src, suffix, editable)。页面与列表适配器禁止再出现裸的 new OpenFileRequest。构建侧可用 BuildProfile 注入默认是否可编辑,但预览入口仍应显式传 false,避免默认值被改成 true 后全站预览可写。

日志建议固定四段:是否已注册、本次 enableEdit、打开 code/msg、是否有 data。Release 截断路径与密钥。合入前全仓搜 enableEdit = true,确认每一处都对应产品上的可编辑入口。审批类页面若同时提供「查看」与「修改」,两个按钮必须走同一 helper、不同布尔,避免复制粘贴后漏改。

真机至少覆盖:冷启动后只读打开、冷启动后可编辑打开、注册未完成点击(应 catch)、故意传外部未拷贝路径(应在拷贝层失败)。换机复测时先确认包名与 HAR 仍匹配。若产品后续要求「编辑完上传」,在模式双绿后再单开回传用例,不要把上传失败误判成 enableEdit 无效。联调清单可贴进内部 Wiki,按周回归;预览可写与编辑只读这类串线通常会明显下降。字段语义以官方对接文档为准,随 SDK 小版本更新封装注释,勿把整张参数表贴进业务页。

七、小结

OpenFileRequest.enableEdit 把鸿蒙 WPS 二开的打开模式收成一个布尔:未设 / false → 只读,true → 可编辑。工程上把注册、沙箱拷贝、模式赋值拆进稳定封装,页面只传 editable。模式稳定后再叠加回传与策略字段;换 HAR 或换包名时先重跑注册与只读打开。把对接文档入口写进 README,发版评审同时看 HAR、注册 code 与本次模式布尔。坚持注册 → 只读 → 可编辑 → 回传的顺序,比一次堆满策略开关更容易定位问题。


基于 WPS Open SDK 鸿蒙版对接实践整理,仅供开发者参考。

官方对接文档:https://365.kdocs.cn/l/clQl5cek2NoT

相关推荐
m0_685535081 小时前
光学设计自学
华为·光学·光学设计·光学工程·镜头设计
懿路向前1 小时前
HarmonyOS 粒子特效实战:马赛克切块提速 17.6×~38×:desiredRegion 重复读盘与一次解码管线(HarmonyOS)
华为·harmonyos
垆边人似月.2 小时前
华为题:LRU 缓存
缓存·华为
天府云创3 小时前
Agentic开发时代到来——鸿蒙PC三大原生开发工具公测
华为·操作系统·harmonyos·鸿蒙系统·cli·deveco·agentic
程序猿追3 小时前
Fleks 鸿蒙适配:从八个小球看实体和组件的变化
华为·harmonyos
Sunny_GMF3 小时前
Markdown 导出 HTML 实战:2.6MB 编辑器快照如何瘦身 71%(DOM 净化 + CSSOM 运行时裁剪)
编辑器·html·ai编程·harmonyos
m0_738185823 小时前
Flutter 鸿蒙化实战:the_apple_sign_in 适配 OpenHarmony,Apple 登录
flutter·华为·harmonyos·鸿蒙
神奇的代码在哪里3 小时前
原生鸿蒙 GBC 模拟器开发实录:用 Anime4K 把 160×144 画面实时放大到 1080P
harmonyos·鸿蒙·超分辨率·gbc模拟器·anime4k
m0_738185824 小时前
Flutter 鸿蒙化实战:umeng_analytics_plugin 适配 OpenHarmony,友盟统计
flutter·华为·harmonyos·鸿蒙
todoitbo4 小时前
把 XAMPP 搬到鸿蒙 PC:在鸿蒙 PC 上跑 Apache httpd 2.4.69实战项目
华为·apache·harmonyos·鸿蒙·开源鸿蒙·鸿蒙pc