在 HarmonyOS 应用中集成 WPS Open SDK 后,OpenFileRequest负责把沙箱内的文档交给 WPS 进程编辑。编辑结束后,最新文件内容往往落在 WPS 自身沙箱,而非调用方传入的原始路径。若业务需要在关窗后继续上传或持久化,必须在请求对象上启用关闭回传(Transfer),并在WPSApi.sendRequest的异步结果里解析Result/ResultData,再把文件同步到本应用沙箱。本文按接口语义说明参数组合、URI 与 FD 两种回传路径的差异,以及filePath落盘的参考实现。
一、关闭回传在调用链中的位置
典型时序如下:应用构造OpenFileRequest并设置wpsTransferType→sendRequest拉起 WPS → 用户编辑并关闭文档 → Promise resolve,此时result.data携带回传信息 → 应用侧拷贝或读 fd → 得到可用于上传的本地路径。
若未配置enableTransferFile或wpsTransferType,sendRequest在 WPS 成功拉起后即可返回code === ResultCode.OK,但data为空。这与「回传成功」是两种语义,UI 层应区分「已打开 WPS」与「已收到回传文件」,避免在data为空时提示保存成功。
二、ResultData 字段说明
Result.data类型为ResultData,与文件回传相关字段如下:
| 字段 | 类型/含义 |
|---|---|
fileUri | URI 模式:WPS 沙箱内临时文件路径 |
transferFd | FD 模式:可读文件描述符 |
transferFileName | FD 模式:建议使用的文件名 |
transferFileSize | FD 模式:字节数,用于校验读入是否完整 |
parameters | 扩展字典,部分版本 FD 信息嵌套在此 |
sendRequest与回传相关的返回语义:
| 场景 | code | data |
|---|---|---|
| 未开回传,拉起成功 | OK | 空 |
| 开启回传,用户关闭且成功 | OK | 含 fileUri 或 transferFd 等 |
| 拉起失败或回传异常 | 非 OK | 视版本可能为空或带错误信息 |
三、开启回传的参数配置
OpenFileRequest上两组相关属性:
| 参数 | 说明 |
|---|---|
enableTransferFile | 为true时按 URI 回传 |
wpsTransferType | TransferType.URI或TransferType.FD,优先于enableTransferFile |
工程上建议只设置wpsTransferType,避免两个开关语义重叠。enableEdit控制是否可编辑,与回传独立,可编辑场景通常同时开启。
import{common}from'@kit.AbilityKit';import{WPSApi,OpenFileRequest,TransferType,ResultCode,}from'@wps/wps_sdk';asyncfunctionopenWithTransfer(ctx:common.UIAbilityContext,sandboxPath:string,mode:TransferType=TransferType.URI){constrequest=newOpenFileRequest(ctx,sandboxPath);request.enableEdit=true;request.wpsTransferType=mode;constresult=awaitWPSApi.sendRequest(request);if(result.code!==ResultCode.OK){thrownewError(result.msg??`WPS error${result.code}`);}returnresult;}四、URI 回传:拷贝到本应用沙箱
URI 模式下,result.data.fileUri指向 WPS 维护的临时文件。三方应用应使用@ohos.file.fs以只读方式打开,再copyFileSync到例如context.filesDir/wps_callback/目录,最后用fileuri.getUriFromPath转为业务使用的 URI。
注意:fileUri不能写入业务数据库作为长期路径;拷贝前需mkdirSync;专业版启用不落地时,拷贝完成后可对 WPS 临时文件执行unlink。
importfsfrom'@ohos.file.fs';importfileurifrom'@ohos.file.fileuri';functioncopyWpsUriToSandbox(ctx:common.UIAbilityContext,wpsFileUri:string):string{constfile=fs.openSync(wpsFileUri,fs.OpenMode.READ_ONLY);constbaseName=wpsFileUri.split('/').pop()??'edited.docx';constdestDir=`${ctx.filesDir}/wps_callback`;fs.mkdirSync(destDir,true);constbackupPath=`${destDir}/${Date.now()}_${baseName}`;fs.copyFileSync(file.fd,backupPath);fs.closeSync(file);returnfileuri.getUriFromPath(backupPath);}五、FD 回传:分块读取与关闭描述符
FD 模式从transferFd分块readSync写入本应用沙箱新文件,写完后必须closefd。实现时建议校验累计读取字节数与transferFileSize一致,否则按失败处理,避免上传残缺文件。大文件可将读写在TaskPool中执行,避免阻塞 UI 线程。
统一入口可先判断 FD,再回退 URI,与官方 Demo 中handleCallbackData/handleCallbackDataByFd的分支顺序一致:
functionresolveCallbackFilePath(ctx:common.UIAbilityContext,result:Result):string|undefined{constdata=result.data;if(!data)returnundefined;if(data.transferFd!==undefined&&data.transferFd>=0){returncopyFdToSandbox(ctx,data);// 按文档 Demo 实现}if(data.fileUri){returncopyWpsUriToSandbox(ctx,data.fileUri);}returnundefined;}六、联调与常见问题
- 回调无 data:未设置
wpsTransferType,或用户未关闭文档即切回应用。 - 上传仍是旧文件:业务仍使用打开前的
sandboxPath,未使用回传拷贝后的路径。 - 拷贝失败:目标目录未创建、沙箱权限不足、文件被占用。
- FD 泄漏:读完后未
closeSync(transferFd)。 - HAR 与凭据不匹配:个人版测试包须使用申请时对应的 SDK 版本。
建议测试矩阵:小 docx / 大 xlsx 各测 URI 与 FD;正常关窗、杀 WPS 进程两种路径;拷贝后用本应用再次打开校验内容 hash。extraOptions、水印等参数与回传无冲突,可配置在同一OpenFileRequest实例上。
错误处理建议
生产代码中应对sendRequest做完整分支:code !== OK时向用户展示result.msg或映射后的错误文案;code === OK && !result.data表示仅打开成功,不应触发上传;data非空但拷贝失败时,与回传失败分开提示,便于定位是 WPS 侧还是应用侧文件系统问题。单元测试可对resolveCallbackFilePath注入 MockResult,覆盖空 data、仅 URI、仅 FD、size 不一致等分支。
与不落地策略的配合
专业版默认不落地时,云文档数据流与本地回传无直接关系,但 URI 模式下 WPS 仍可能产生临时文件。拷贝到本应用沙箱后,若安全策略要求最小化残留,应在确认上传成功后再删除 WPS 临时路径与本应用中间文件。个人版与个人版 HAR 的接口与专业版一致,联调时注意包名、签名与申请凭据对应,避免回调字段缺失被误判为未开回传。
七、小结
关闭回传把 WPS 编辑能力从「单向打开」扩展为「可回写」:wpsTransferType声明传输层形态,sendRequest的 Promise 承载关窗结果,应用侧负责沙箱拷贝与后续业务消费。实现时固定「解析 Result → 拷贝/fd 读入 → 上传或落库」三层,URI/FD 仅影响第二步的具体 API 调用。
基于 WPS Open SDK 鸿蒙版对接实践整理,仅供开发者参考。
官方对接文档:https://365.kdocs.cn/l/clQl5cek2NoT
技术交流 QQ 群:628436767