HarmonyOS WPS Open SDK:打开链路叠加水印与修订配置
HarmonyOS 工程接入 @wps/wps_sdk 后,本地文档打开通常先跑通 registerApp、沙箱路径与 enableEdit。产品下一步常会要求「预览页打水印」或「以修订模式进入文档」。对接文档把这两类能力挂在同一次 OpenFileRequest 上:水印走 wpsWaterMarkParams(类型 WaterMark),修订走 wpsRevisionParams(类型 Revision)。它们不是第二条打开 API,而是打开策略层字段。本文按调用链写清字段语义、与只读/可编辑的叠加顺序、可复用封装与联调清单。字段以官方对接文档为准。
一、策略层在打开链路中的位置
固定顺序:HAR 集成 → registerApp 回调到 ResultCode.OK → 按凭据约定可选注入激活序列号 → 文件进入本应用沙箱 → new OpenFileRequest(context, path) → 设置 enableEdit →(可选)写入水印 / 修订 → WPSApi.sendRequest。
| 层级 | 职责 | 入口 |
|---|---|---|
| 门禁 | 注册成功才允许打开 | registerApp / ResultCode.OK |
| 路径 | 选择器 URI 拷进沙箱 | filesDir 拷贝 |
| 模式 | 只读或可编辑 | enableEdit |
| 策略 | 水印、修订 | wpsWaterMarkParams / wpsRevisionParams |
| 结果 | 关窗回传(可选) | wpsTransferType |
水印与修订属于策略层,不要和「能否打开」绑在同一个匿名点击回调里同时改。联调建议:注册 → 沙箱只读 → 可编辑 → 再叠水印或修订 → 最后回传。一次写满全部开关时,ResultCode.ERROR 很难归因。
二、WaterMark 字段语义
类型:WaterMark,赋给 request.wpsWaterMarkParams。
| 属性 | 说明 |
|---|---|
Enable | 是否启用水印 |
WaterMaskText | 水印文字 |
Angle | 旋转角度 |
FontColor | 颜色(可含透明度),如 "#19000000" |
FontSize | 字号 |
常见漏项:只 new WaterMark() 却未设 Enable = true;文字为空却期望看见水印;对象建了却未赋给 Request。封装时应写完字段再赋值。水印可与只读同时存在:预览场景不必强行 enableEdit = true。颜色过淡时,联调可先用对比更明显的组合确认逻辑,再交给设计调淡。
import { WaterMark, OpenFileRequest } from '@wps/wps_sdk';
function applyWatermark(req: OpenFileRequest, text: string): void {
const wm = new WaterMark();
wm.Enable = true;
wm.WaterMaskText = text;
wm.Angle = -30;
wm.FontColor = '#19000000';
wm.FontSize = 24;
req.wpsWaterMarkParams = wm;
}
三、Revision 字段语义
类型:Revision,赋给 request.wpsRevisionParams。
| 属性 | 说明 |
|---|---|
UserName | 修订作者名称 |
EnterReviseMode | 是否以修订模式打开 |
ShowRevisionPanel | 是否显示修订面板 |
EnterRevisionSilent | 是否静默进入(不弹提示) |
修订痕迹依赖可编辑。若 enableEdit 仍为只读,用户侧常感觉「修订没生效」。EnterRevisionSilent 适合减少打扰,联调日志仍要打出是否进入修订。UserName 建议与业务登录名或工号对齐,便于事后追溯。
import { Revision } from '@wps/wps_sdk';
function applyRevision(req: OpenFileRequest, user: string, silent: boolean): void {
const rev = new Revision();
rev.UserName = user;
rev.EnterReviseMode = true;
rev.ShowRevisionPanel = true;
rev.EnterRevisionSilent = silent;
req.wpsRevisionParams = rev;
}
四、注册就绪与路径前提
未注册成功就 sendRequest 会抛异常,此时讨论水印无效。把注册收成可 await 的准备;换 HAR 或换正式包包名后 clean,再验注册。1013(ERROR_CODE_AUTH_FAILURE)出现在注册阶段时,停止改策略字段,先对齐 bundleName、appKey / appSecret 与 HAR。
import { WPSApi, Result, ResultCode } from '@wps/wps_sdk';
let ready = false;
export function prepareWps(key: string, secret: string, sn?: 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 (sn) {
WPSApi.setWpsFileToken(sn);
}
ready = true;
resolve();
},
});
});
}
路径建议先拷到沙箱:外部 URI 权限不足时常见泛化 ERROR,容易被误判成「水印没生效」。需要序列号时在注册成功回调里全局注入,不要写 OpenFileRequest.wpsToken。Release 禁止打印完整 appSecret。
五、可复用打开封装
把模式、水印、修订做成可选参数,页面不直接 new OpenFileRequest。
import { common } from '@kit.AbilityKit';
import { OpenFileRequest, Result, WPSApi } from '@wps/wps_sdk';
export type OpenMode = 'preview' | 'edit';
export interface OpenPolicy {
watermarkText?: string;
revisionUser?: string;
revisionSilent?: boolean;
}
export async function openDoc(
ctx: common.UIAbilityContext,
src: string,
mode: OpenMode,
policy: OpenPolicy = {}
): Promise<Result> {
await prepareWps(APP_KEY, APP_SECRET);
const path = copyToSandbox(ctx, src);
const req = new OpenFileRequest(ctx, path);
req.enableEdit = mode === 'edit';
if (policy.watermarkText) {
applyWatermark(req, policy.watermarkText);
}
if (policy.revisionUser) {
applyRevision(req, policy.revisionUser, !!policy.revisionSilent);
}
return WPSApi.sendRequest(req);
}
产品临时加「预览也要水印」,只扩 policy,不新开平行 Helper。关窗回传仍用独立字段,与水印/修订解耦:未开回传时 ResultCode.OK 且 data == null 表示拉起成功,不代表「已同步」。
六、联调表与日志
| 现象 | 优先查 |
|---|---|
| 抛异常 | 是否等注册完成 |
1013 | 凭据 / 正式包包名 / clean |
| 无水印 | Enable、文字、是否赋给 Request |
| 无修订 | EnterReviseMode、是否可编辑 |
| 泛化 ERROR | 路径是否沙箱 |
日志固定:code / msg / ready / 沙箱 / enableEdit / 是否带水印 / 是否进修订。全仓 new OpenFileRequest 命中保持一处。推荐验收两条用例:只读预览 + 水印;可编辑 + 修订(静默开/关各测一次)。两条都绿后,再决定是否叠加关窗回传。
七、小结与工程落地建议
鸿蒙侧 WPS Open SDK 的水印与修订,是打开策略层能力:在 enableEdit 跑绿后再叠 WaterMark / Revision。字段必须显式赋值;封装用可选策略对象收口。路径进沙箱、注册先就绪、回传另算一层。字段语义以官方对接文档为准。
接入评审可逐项确认:当前 HAR 批次与包名是否匹配、沙箱目录约定是否统一、策略是否全部走 Facade、正式包与调试包的凭据是否分开归档。把「先模式后策略」写进联调清单后,排查会从猜原因变成对表。换 HAR 后务必 clean 再装;水印文字与修订作者名做成可配置项,比写死在页面里更利于运营调整。注释写清「本项目约定:水印与修订只走 Facade」,比口头说「参考 Demo」更耐看。
真机验收可拆成两条固定用例:其一「只读预览 + 水印」,其二「可编辑 + 修订(含静默开关各测一次)」。两条都绿后,再决定是否叠加关窗回传。若产品临时要求「预览也要水印」,只扩 Facade 的可选参数,不要新开平行 Helper。全仓检索 new OpenFileRequest 的命中数应保持为一;页面层只调用 openDoc。周五用正式包包名再验注册,并对照日志里的 ready、沙箱、enableEdit、是否带水印、是否进修订,确认策略相关误报是否下降。
从协作角度看,颜色与角度属于视觉参数,联调阶段可先用对比明显的组合确认逻辑,再交给设计调淡。修订面板是否展示、是否静默进入,应在需求文档里写清默认值,避免不同页面各自猜。路径拷贝失败时要有明确错误提示,否则用户只会说「打不开」或「没有水印」,研发侧难以及时定位。Ability 启动阶段完成注册,进入文档页前 ready 已同步到 UI;点开时再构造 Request,不要在 aboutToAppear 里预建一堆策略对象。Release 包禁止打印完整 appSecret;水印全文若含敏感信息,日志侧只打文字长度更稳妥。把上述约定坚持几周,策略层相关的反复提问通常会明显减少,接入节奏也会更稳。
基于 WPS Open SDK 鸿蒙版对接实践整理,仅供开发者参考。
官方对接文档:https://365.kdocs.cn/l/clQl5cek2NoT
更多推荐


所有评论(0)