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

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

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

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

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

二、enableEdit 语义与对照

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

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

构造签名不变:

new OpenFileRequest(context: UIAbilityContext, fileUri: string)

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

三、注册门禁与沙箱路径

模式实验建立在注册成功之上。未到 ResultCode.OKsendRequest 会抛异常,该异常不是带 code 的打开 Result1013ERROR_CODE_AUTH_FAILURE)出现在注册阶段时,停止改 enableEdit,先对齐 bundleNameappKey / appSecret 与 HAR。

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 前保持禁用。

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。用第四个布尔参数区分模式:

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.onCreatebootstrap,页面 aboutToAppear 只读 isReady(),点击里调用 openLocalinterpretOpen。列表多附件时循环只调封装,禁止每项内联构造 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

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐