PlantUML 多语言支持:CJK 字体、RTL、Unicode 字符、emoji 的全部配置
PlantUML 是 JVM / Java 写的,理论上 unicode 全兼容——但实际「中文 / 日文 / 阿拉伯文 / emoji」各自踩不同的坑,这一篇一次性整理。
CJK:中文 / 日文 / 韩文
默认会变「豆腐」
PlantUUM 默认用 Java Logical Font——Linux 上没有 CJK 字体 → 显示成 □□□。
1 | Alice -> Bob: 你好 # 渲染成 "□□□" |
解决方案:指定字体
1 | @startuml |
支持的常见 CJK 字体:
| 字体 | 系统 | 推荐度 |
|---|---|---|
| Noto Sans CJK SC | Linux/跨平台 | ⭐⭐⭐⭐⭐ |
| Noto Sans CJK TC | 台湾繁体 | ⭐⭐⭐⭐⭐ |
| Source Han Sans SC | macOS/Adobe | ⭐⭐⭐⭐⭐ |
| Microsoft YaHei | Windows | ⭐⭐⭐ |
| PingFang SC | macOS 中文 | ⭐⭐⭐⭐ |
| WenQuanYi Micro Hei | Linux 旧版 | ⭐⭐ |
| Sarasa Mono SC | 等宽场景 | ⭐⭐⭐ |
字体回退(fallback)
如果指定字体没有某种 unicode 字符,应该回退到另一个字体。这在 PlantUML 是有限支持:
1 | @startuml |
但 PlantUML 内部 font-family 传给 Graphviz / PlantUML Skia 渲染引擎——fallback 行为实际依赖底层引擎,不保证 100% 工作。
更稳的方案:保证单字体已经覆盖了所需字符范围。
字体安装:服务端
如果你用 plantuml-server(docker):
1 | # 在 Dockerfile 里装 Noto |
或者用官方 plantuml/plantuml-server 镜像,已经内置 Noto CJK。
字体安装:客户端
如果用 TeaVM PlantUML(浏览器跑 plantuml.js),TeaVM 本身只内置了有限字体——CJK 显示成方块。
自托管 TeaVM + 自带字体:
1 | <!-- 显式注入字体到文档里 --> |
但 PlantUML 渲染在 Canvas / SVG 里,font-face 并不会自动注入到 Canvas——需要 SVG <text> 节点的 inline font-family + 字体 base64 内嵌。
1 | // 渲染后处理 |
注意:浏览器对 SVG <text> 元素的 data-font 自定义字段支持有限。最稳方案是改 PlantUML 的字体配置—— TeaVM 自带字体可重新打包。
字体嵌套(woff2 base64)
如果一定要塞进 SVG:
1 | # 把 Noto Sans CJK SC 切成子集(只包含你需要的字符) |
得到 ~150KB woff2 → base64 嵌入 SVG(SVG 文件会突然增大 100KB)。
Unicode 字符范围
中文标点
1 | @startuml |
大部分 CJK 字体(Noto / 思源黑体)已覆盖中文标点:
- 中文括号:
() - 全角空格:
- 中文标点:
,。;:!? - 引号:
「」""『』 - 破折号:
——
表情符号 emoji
PlantUML 支持 emoji 但依赖底层渲染引擎:
1 | @startuml |
注意 :smile: 这种是 PlantUML 自定义的 short code,只在 preprocessor $ 模式下生效。
如果想要直接 emoji:
1 | @startuml |
| 字体 | emoji 支持 | 备注 |
|---|---|---|
| Noto Sans CJK | 部分 | 旧版本 emoji 缺失 |
| Apple Color Emoji | ✅ | macOS 系统字体 |
| Noto Color Emoji | ✅ | Linux/Android 字体 |
| Segoe UI Emoji | ✅ | Windows 系统字体 |
PlantUML 默认 不保证 emoji 渲染,要看你引用的字体库。
组合字符(combining diacritics)
a + ̃ 这种字素组合(如越南语、阿拉伯语),PlantUML 通常能渲染,但字距可能错。
1 | @startuml |
RTL 文字(阿拉伯文 / 希伯来文)
PlantUUM 的 layout 算法是 Graphviz 的 dot——自然支持 RTL:
1 | @startuml |
但注意:
- 节点名用 RTL 字符没问题
- 消息文字也是 RTL 字符 → 自动镜像(layout)
- 顺序:
actor A在「左」还是「右」要看 bidi 算法
如果你想强制 RTL 渲染布局:
1 | @startuml |
PlantUML 限制:单行的 RTL 文本自动 bidi 算法对图标题 / 带 RTL 字符的 layout 经常生成奇怪布局。你可能要手动微调 top to bottom direction 或 left to right direction。
Arab / Hebrew 在 CJK 字体
如果你选了 Noto Sans CJK SC 这个字体,它不覆盖阿拉伯文。多字体 fallback:
1 | @startuml |
但 PlantUML 实际渲染的字体回落取决于底层引擎——测试验证才能确定哪种字体真正生效。
等宽 / monospace
代码场景需要 monospace:
1 | @startuml |
end note
@enduml
1 |
|
2. plantuml CLI 渲染
1 | plantuml -tsvg test.puml |
打开 SVG 在 Chrome / Safari 看:
- ✅ 中文显示正常
- ⚠️ emoji 方块 → 字体缺
- ✅ 希腊字母显示
- ⚠️ 西里尔字母方块 → 字体缺
3. 修复 + 重新
1 | @startuml |
4. CI 验证
1 | # 渲染 → 检查 SVG 内的 CJK 字符 |
更稳的方式:使用 SVGO 紧凑 SVG,提取 <text> 节点的实际字符内容。
PlantUML 内部的 unicode 处理
文件编码
.puml 文件必须 UTF-8 保存——这是 PlantUML 的硬性要求。Windows 用 ANSI 保存会失败或乱码。
BOM(字节序标记)
避免 —— PlantUML 1.2020+ 的 parser 能吃 BOM 但不保证。建议:
1 | # 移除 UTF-8 BOM |
团队协作中的多语言实战
一个常见的痛
「我看到的是
□□□,同事看到的是中文」
根因:team member 各自本地字体不同。最稳方案:
- CI 渲染图 → 截图 → 合并到 release
- render 结果不含字体(SVG 不内嵌字体文件)
- 浏览图的人没装 Noto → 自己看到豆腐
根治:SVG 内嵌 woff2 base64。或者用 PDF 输出(在客户端通常自动 fallback 字体)。
文件组织建议
1 | docs/diagrams/ |
每改一行 puml,CI 渲染所有语言的 SVG → 上传到 wiki。
PlantUML 中的 i18n 模板
puml 中不直接支持 i18n 函数,但 !define + $ 可变:
1 | @startuml |
实际环境变量需要在调用 plantuml CLI 时注入:
1 | plantuml -DLANG=zh -tdefault test.puml |
多语言源代码的 git 工作流
把不同语言 source 写在 git 仓库:
1 | docs/diagrams/ |
1 |
|
CI 跑:bash render.sh → 发布到 wiki。
高级:CJK 等宽 / 非等宽混合
1 | @startuml |
字体回退链路:
- Inter → 拉丁字母漂亮
- 命中 CJK 字符 → 回退到 Noto Sans CJK SC(如果设置了 fallback)
PlantUML + skinparam 多字体语法:
1 | skinparam defaultFontName "Inter" |
实战建议清单
- 生产用 Noto Sans CJK SC——开源、字符覆盖全、Linux/Mac/Windows 都好装
- CI 服务端装好 CJK 字体——docker 镜像构建时
apt-get install fonts-noto-cjk - TeaVM 客户端就别想了——字体注入太麻烦,改用 plantuml-server
!theme cyborg/!theme dark——避开字体黑名单- CJK 字符占位较宽——Graphviz dot 算法会算 CJK 字符宽度,设
skinparam nodesep 40给点空间 skinparam dpi——配合 CSS 让图放大时不糊
落地 puml.online 的具体决策
我们的项目:
- 大部分图 CJK 注释 → 用 Noto Sans CJK SC
- TeaVM WASM 编辑器渲染 → fallback 到 plantuml.com(TeaVM 不支持 CJK 字体)
- CI 渲染 → docker 镜像内置 Noto
不需要扩展 unicode 复杂度。
小结
- PlantUML unicode 实际分三层:字体可用性、RTL 算法、emoji 兼容
- CJK 主要坑:字体不存在 —— 默认 JVM 字体是不带 CJK 的
- Noto Sans CJK SC + 服务端 docker 内置 是 95% 的生产方案
- TeaVM + 客户端:放弃 CJK,改用 plantuml.com
下一步
- 标题: PlantUML 多语言支持:CJK 字体、RTL、Unicode 字符、emoji 的全部配置
- 作者: puml.online
- 创建于 : 2026-07-30 12:10:00
- 更新于 : 2026-08-14 21:34:29
- 链接: https://puml.online/blog/plantuml-multilingual-notes/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。