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,再验注册。1013ERROR_CODE_AUTH_FAILURE)出现在注册阶段时,停止改策略字段,先对齐 bundleNameappKey / 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.OKdata == 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

Logo

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

更多推荐