ARTICLE · 1351176
SpringBoot+OnlyOffice:在线 Word 编辑、转化、保存,一套方案搞定
如果让后端自己解析 DOCX、处理编辑操作、再重新生成文件,这条路很快就会走复杂。尤其是表格、页眉页脚、图片、分页这些东西,稍微处理不好,文档格式就乱了。
我的思路是:文档编辑交给 OnlyOffice,业务管理交给 SpringBoot,文件存储由自己的服务负责。 这几个边界划清楚,后面维护起来会省心不少。
一、先把整体流程跑通

整体架构并不复杂。
前端通过 OnlyOffice 的 JavaScript API 加载 Word 编辑器。 SpringBoot 负责生成编辑器配置,并提供文档下载地址。 OnlyOffice Document Server 负责真正的文档编辑和格式转换。 用户点击保存后,OnlyOffice 将编辑结果通过回调通知 SpringBoot。 SpringBoot 下载最新文件,再保存到文件服务器或对象存储。
这里有个容易搞错的地方:用户在编辑器里按下保存,不代表你的 SpringBoot 服务已经拿到了最新文件。 文档保存通常涉及 OnlyOffice 的回调机制,后端必须正确处理回调状态。
部署时,SpringBoot 和 OnlyOffice Document Server 需要能够通过网络互相访问。如果启用了 JWT,还要保证两边的密钥配置一致。
二、SpringBoot 生成编辑器配置
假设数据库里保存了文档 ID、文件名和存储路径。用户打开文档时,后端根据文档 ID 查询元数据,生成编辑器需要的配置。
下面以 SpringBoot、Java 为例,演示核心配置。documentUrl 是 OnlyOffice 能够访问的文件下载地址,不能随便填一个浏览器本地地址。
public Map<String, Object> buildEditorConfig(
String docId, String documentUrl, String userId) {
Map<String, Object> document = new HashMap<>();
document.put("fileType", "docx");
document.put("key", docId + "-" + System.currentTimeMillis());
document.put("title", "项目方案.docx");
document.put("url", documentUrl);
Map<String, Object> permissions = new HashMap<>();
permissions.put("edit", true);
permissions.put("download", true);
Map<String, Object> config = new HashMap<>();
config.put("document", document);
config.put("documentType", "word");
config.put("editorConfig", Map.of(
"mode", "edit",
"user", Map.of("id", userId, "name", "文档编辑者")
));
return config;
}
这段代码展示的是配置结构,生产环境还需要补齐权限校验、JWT 签名以及文件元数据查询。
尤其是 document.key,不要一直使用固定值。OnlyOffice 会利用它识别文档版本和缓存,同一份文档在内容更新后,应使用能够区分版本的 key,否则可能遇到编辑器仍然加载旧内容的问题。
另外,示例中的 permissions 只是展示权限数据的写法,实际使用时要把它放进 OnlyOffice 对应的配置节点,并根据业务角色控制编辑权限。
三、保存才是真正需要注意的地方
OnlyOffice 编辑器会向后端指定的 callbackUrl 发送保存状态。后端收到回调后,需要根据状态判断是否应该下载最新文件。
常见的状态中,2 表示文档已准备好保存,6 表示强制保存完成。具体处理逻辑应结合部署版本和实际回调行为确认。
@PostMapping("/onlyoffice/callback/{docId}")
public Map<String, Object> saveCallback(
@PathVariable String docId,
@RequestBody Map<String, Object> body) {
int status = ((Number) body.get("status")).intValue();
if (status == 2 || status == 6) {
String downloadUrl = (String) body.get("url");
// 下载最新 DOCX 文件,校验后写入存储
documentStorageService.saveLatest(docId, downloadUrl);
}
return Map.of("error", 0);
}
这里的 documentStorageService 是业务层封装,实际实现需要通过 HTTP 下载回调提供的文件,并将文件持久化。示例省略了异常处理和具体存储实现。
还有三个细节不能省。
第一,回调接口必须验证 JWT,不能让外部请求随便传一个文件 URL 就触发服务器下载,否则可能引入伪造回调和 SSRF 风险。
第二,保存操作要考虑重复回调。建议结合文档版本、保存任务记录或内容校验实现幂等,避免重复写入产生问题。
第三,文件下载失败不能直接返回保存成功。要记录文档 ID、回调状态和异常信息,必要时提供重试机制。否则用户看到编辑器已经保存,业务系统里的文件却还是旧版本,排查起来很麻烦。
四、Word 转 PDF,别自己折腾格式
如果系统还需要导出 PDF,OnlyOffice 提供了文档转换接口,可以将 DOCX 转为 PDF。SpringBoot 负责调用转换服务、检查结果,再把生成的 PDF 保存到业务存储中。
实际项目里,转换任务最好独立封装,并处理超时、失败重试以及临时文件清理。文档量比较大时,还可以放进异步任务队列,避免转换操作长时间占用 HTTP 请求线程。
最后还有一个经常被忽略的问题:文档保存和格式转换不要共用一套不加区分的缓存策略。 Word 更新后,如果 PDF 仍然使用旧版本的转换结果,用户下载到的文件就会出现内容不一致。可以用文档 ID 加版本号作为转换任务的唯一标识,更新 Word 后再重新生成 PDF。
SpringBoot 和 OnlyOffice 的分工其实很明确:编辑、渲染、转换交给文档服务,权限、业务状态、版本管理和持久化留在自己的系统里。把保存回调和版本控制处理好,这套方案就能支撑大多数在线文档管理场景。















































































