HarmonyOS WPS Open SDK:OpenFileRequest 打开本地文档实现
在 HarmonyOS 应用里接入 @wps/wps_sdk 后,业务最常见的验收点是「点一下能打开 Word」。真正落到工程时,打开能力集中在 OpenFileRequest:构造参数要沙箱可读路径,enableEdit 决定只读或可编辑,WPSApi.sendRequest 负责拉起 WPS 并返回 Result。本文按注册 → 拷贝 → 打开 → 结果处理的顺序说明最小可运行链路;字段语义以官方对接文档为准。
一、打开能力在调用链中的位置
典型时序:registerApp 回调 ResultCode.OK →(按凭据约定可选注入激活序列号)→ 把待打开文件拷到应用沙箱 → new OpenFileRequest(context, path) → 设置 enableEdit 等字段 → sendRequest 拉起 WPS。
| 步骤 | API / 动作 | 失败时常见表现 |
|---|---|---|
| 注册 | registerApp |
未 OK 就打开会抛异常 |
| 路径 | copyFileSync 到 filesDir |
外部 URI 权限不足 → 泛化 ERROR |
| 打开 | OpenFileRequest + sendRequest |
code / msg 非 OK |
| 结果 | Promise<Result> |
未开回传时 data 为空属正常 |
一次写满水印、extraOptions、回传开关时,ResultCode.ERROR 很难归因。联调应先跑通「注册 → 沙箱只读打开」,再开 enableEdit = true。
二、注册必须先成功
对接文档要求:注册成功之前调用其它 sendRequest 会抛异常。这不是「打开失败」,而是请求链未就绪。建议把注册写成可 await 的一次性准备,并加就绪标记。
import {
WPSApi,
OpenFileRequest,
Result,
ResultCode,
} from '@wps/wps_sdk';
let ready = false;
function prepareWps(
key: string,
secret: string,
activationSn?: string
): Promise<void> {
return new Promise((resolve, reject) => {
if (ready) {
resolve();
return;
}
WPSApi.registerApp(key, secret, {
onCallback: (result: Result): void => {
if (result.code === ResultCode.ERROR_CODE_AUTH_FAILURE) {
reject(new Error(`1013: ${result.msg ?? ''}`));
return;
}
if (result.code !== ResultCode.OK) {
reject(new Error(`register ${result.code}`));
return;
}
if (activationSn) {
WPSApi.setWpsFileToken(activationSn);
}
ready = true;
resolve();
},
});
});
}
冷启动可在 Ability 里 await prepareWps;首页打开按钮在 ready 前禁用。Release 不要打印完整 secret。凭据与 bundleName 绑定,换 HAR 或换正式包名后务必 clean,再核对是否仍返回 1013。
三、路径:先落沙箱再交给 OpenFileRequest
构造签名为 new OpenFileRequest(context, fileUri)。context 为当前 UIAbilityContext,fileUri 建议为本应用沙箱内可读路径。从系统文件选择器拿到的路径,往往因权限不足导致 WPS 读不到;实践里先 copyFileSync 再打开更稳。
import { common } from '@kit.AbilityKit';
import fs from '@ohos.file.fs';
function toSandbox(ctx: common.UIAbilityContext, src: string): string {
const dir = `${ctx.filesDir}/wps_open`;
fs.mkdirSync(dir, true);
const dest = `${dir}/${Date.now()}.docx`;
fs.copyFileSync(src, dest);
return dest;
}
目录名可按业务划分(预览、审批附件等),但全仓打开入口应共用同一拷贝函数,避免各页面各写一套临时目录规则。
四、enableEdit:默认只读是能力语义
enableEdit |
打开模式 |
|---|---|
未设置 / false |
只读(ReadOnly) |
显式 true |
可编辑(Normal) |
预览入口与编辑入口应共用同一打开函数,只差布尔参数,避免两套 new OpenFileRequest 漂移。需要关窗回传时再赋 wpsTransferType,与可编辑开关独立——不要默认「能编辑就一定回传」。
export async function openDoc(
ctx: common.UIAbilityContext,
src: string,
editable: boolean
): Promise<Result> {
await prepareWps(APP_KEY, APP_SECRET, ACTIVATION_SN_OR_EMPTY);
const path = toSandbox(ctx, src);
const req = new OpenFileRequest(ctx, path);
req.enableEdit = editable;
return WPSApi.sendRequest(req);
}
ACTIVATION_SN_OR_EMPTY 由构建配置注入:需要序列号的变体传真实值,不需要的变体传空,让 prepareWps 跳过 Token。不推荐在每次 Request 上重复塞 wpsToken。
五、sendRequest 与 Result 怎么读
sendRequest 返回 Promise<Result>。未注册成功时走异常(.catch),注册后打开失败则多在 result.code / result.msg。联调日志建议固定打印:code、msg、是否 ready、路径是否沙箱、是否 enableEdit。
| 场景 | 处理建议 |
|---|---|
| Promise reject / 抛异常 | 是否等 prepareWps 完成 |
1013 |
key/secret/bundleName 与申请是否一致 |
| 泛化 ERROR | 路径是否沙箱、Context 是否有效 |
| OK 且未开回传 | data 为空属正常,勿提示「已保存」 |
策略字段(水印、extraOptions、落地相关)放到只读/可编辑都绿之后再叠。extraOptions 仅显式赋值的字段生效。
六、工程纪律与联调清单
建议写进 PR 模板:
- 全仓只有一处
new OpenFileRequest - 页面只调用
prepare/open,不直连 SDK - 换 HAR 后 clean;正式包包名再验注册
- 真机至少验只读与可编辑各一次
- Release 不打印完整
appSecret
多人协作时冻结平行 Helper:产品临时要求预览水印或关窗回传,只扩 Facade 可选参数。字段与错误码仍以官方对接文档为准,随 SDK 小版本核对。
七、小结
OpenFileRequest 打开文档的本质是四句话:注册等到 OK、文件进沙箱、只读先绿再开编辑、结果用 code/msg 归因。统一版把打开面收敛到一套 API,工程上仍须把路径与注册时序做对。把 prepareWps / openDoc 固化后,预览与编辑只差一个布尔值,后续叠策略也不会再复制第三套打开代码。
再补一段工程侧提醒:接入评审时把「当前 HAR、凭据环境、是否注入序列号、沙箱目录约定」写成一页对照表。测试按表验收,比口头说「都能打开」靠谱。两周后再搜一次全仓 new OpenFileRequest 命中数,比写长接入说明更能证明封装落地。外部 URI 权限不足时常见泛化 ERROR;正式包与调试包包名不同时,凭据批次分开归档,避免「本地绿、上架红」。
冷启动注册、打开按钮禁用、正式包再验注册,这三件事做成检查表后,新人合入打开相关代码会稳很多。若产品临时要求预览水印或关窗回传,仍然只改 openDoc 可选参数,不新开平行文件。换 HAR 后 clean;不要在 Release 打印完整 appSecret;不要在 Request 上重复塞 wpsToken。把「先绿再叠」写进联调清单:注册 → 只读 → 可编辑 → 策略 → 回传,联调通常会从猜原因变成对表排查。字段语义继续以官方对接文档为准,随 SDK 小版本更新注释,而不是把整张参数表贴进业务页。
基于 WPS Open SDK 鸿蒙版对接实践整理,仅供开发者参考。
官方对接文档:https://365.kdocs.cn/l/clQl5cek2NoT
更多推荐
所有评论(0)