写 PlantUML 时,10 张图共用同一套皮肤和图例?预处理指令能让你抽出共用代码。写文档配好看的图标?图标库让图更直观。两件事一起做效率最高。
预处理指令速查
指令
用途
!include <url>
引入外部 PlantUML 文件 / 文本
!includeurl <url>
从 URL 引入
!include_once
include 但只在第一次生效
!define <VAR> <value>
定义预处理变量
!function <name>(args)
定义预处理函数
%variable_name
引用预处理变量
%date("format")
当前日期
%dirpath(...) / %filename(...)
文件名相关
!if / !else / !endif
预处理条件
!definelong
跨行定义
%load_json / %load_yaml
读外部 JSON / YAML
1. !include(最常用) 抽共用样式到一个文件:
1 2 3 4 5 6 # source/plantuml/_theme.puml !define THEME_DARK skinparam backgroundColor #FAFAFA skinparam BorderColor #2F4858 skinparam ArrowColor #2F4858 skinparam FontColor #1F2328
主文件用它:
1 2 3 4 5 6 7 8 @startuml !include /path/to/_theme.puml class Order class Product Order --> Product @enduml
每次渲染的时候,会自动把 _theme.puml 内容替换进去。
内网部署注意 :企业内网访问 GitHub raw URL 会失败,要么本地 vendor,要么用 !include 本地路径。
!include_once vs !include
!include 每个 @startuml 段都会加载一次
!include_once 在 .puml 文件生命周期内只加载一次
大多数情况用 !include。
!include 整段 1 2 3 4 5 6 7 8 9 10 @startuml !include ../plantuml/c4/C4_Container.puml Person(user, "用户") Container(web, "Web", "React") Container(api, "API", "Go") Rel(user, web) Rel(web, api) @enduml
!include C4-PlantUML 标准库,实现标准化。
!include 文件路径分隔 1 2 !include ../shared/styles.puml !include ../../c4/C4_Container.puml
2. !define / %variable 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @startuml !define COLOR_PRIMARY #A31F34 !define COLOR_SUCCESS #20A464 !define COLOR_WARNING #F4B40A skinparam class { BackgroundColor %COLOR_PRIMARY FontColor white } class A class B A -> B @enduml
!define 定义一个预处理变量,%variable_name 使用。
多变量 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @startuml !define COLOR_PRIMARY #A31F34 !define COLOR_BG #FAFAFA !define ARROW_WIDTH 2 !define FONT_NAME "PingFang SC" skinparam { BackgroundColor %COLOR_BG ArrowColor %COLOR_PRIMARY FontName %FONT_NAME } class A A -> B @enduml
跨行定义 !definelong 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @startuml !definelong STYLE_CLASS_PRIMARY skinparam class { BackgroundColor #A31F34 FontColor white BorderColor white } !enddefinelong STYLE_CLASS_PRIMARY class A class B @enduml
3. !function(预处理函数) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 @startuml !function $accent($type) !if ($type == "primary") !return #A31F34 !else !return #6B7280 !endif !endfunction class A A -> B : %accent("primary") A -> C : %accent("warning") @enduml
!function + !return 创建函数。!if 写条件。
实际例子:状态颜色 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @startuml !function $status_color($s) !if ($s == "ok") !return #20A464 !elseif ($s == "warn") !return #F4B40A !elseif ($s == "fail") !return #DC2626 !else !return #6B7280 !endif !endfunction skinparam class { BackgroundColor $status_color("ok") } class Healthy @enduml
4. %date / %time 1 2 3 @startuml title 报告生成于 %date("yyyy-MM-dd HH:mm") @enduml
%date("...") 用 Java SimpleDateFormat 模式:
模式
输出
yyyy-MM-dd
2026-07-29
yyyy
2026
MM/dd/yy
07/29/26
dd MMM yyyy
29 Jul 2026
标题加日期 1 2 3 4 5 6 7 8 @startuml title 系统状态 - %date("yyyy-MM-dd") class Service1 class Service2 class Service3 @enduml
文档每次生成时自动加日期。
5. !if / !endif 1 2 3 4 5 6 7 8 9 10 11 12 13 @startuml !define DEBUG true !if (DEBUG == true) skinparam class { BackgroundColor #F4B40A BorderColor #DC2626 } !endif class Order @enduml
!if / !else / !endif 控制哪些行被包含。
多分支 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @startuml !define THEME "dark" !if (THEME == "dark") skinparam BackgroundColor #161B22 skinparam FontColor #E6EDF3 !elseif (THEME == "light") skinparam BackgroundColor #FAFAFA skinparam FontColor #1F2328 !else skinparam BackgroundColor white skinparam FontColor black !endif class Order @enduml
实战:用命令行切换主题 1 2 3 plantuml -DTHEME=dark *.puml plantuml -DTHEME=light *.puml
传给 plantuml.jar 的 -D 定义就会被 !define 读取。
6. %load_json / %load_yaml 读外部数据源:
1 2 3 @startjson %load_json("data.json") @endjson
读外部 JSON 文件当 PlantUML 输入。
实际工作流:
1 2 3 4 5 6 cat <<EOF | java -jar plantuml.jar -pipe >out.svg @startjson %load_json("$1") @endjson EOF
输出的 SVG 把 JSON 渲染成树形图。
图标库(OpenIconic / FontAwesome) PlantUML 支持工业标准的开源图标库,让类图 / 组件图 / 部署图更具表意力。
OpenIconic 1 2 3 4 5 6 @startuml class Application <<&person>> database Database <<&cylinder>> @enduml
<&<icon_name>> 引用 OpenIconic 图标。常用:
代码
图标
<&person>
用户
<&cog>
齿轮 / 设置
<&lock-locked>
锁
<&check>
勾
<&x>
叉
<&bell>
铃
<&calendar>
日历
<&graph>
图表
<&database>
数据库
<&cloud>
云
<&bolt>
闪电
完整内置 stereotype 1 2 3 4 5 6 7 8 9 10 @startuml class Server <<&server>> class Database <<&database>> class Queue <<&queue>> class Network <<&network>> class Storage <<&storage>> class User <<&user>> @enduml
FontAwesome 1 2 3 4 5 6 7 8 9 10 11 12 @startuml !include <material/common> !include <material/server> !include <material/database> node "API Gateway" as gw <<$material/server>> database "Postgres" as db <<$material/database>> gw --> db @enduml
!include <material/...> 或 !include <aws/...> 引入图标库。
Material Icon 库 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @startuml !include <material/common> !include <material/server> !include <material/database> !include <material/globe_network> !include <material/api> class User <<$material/account>> class API <<$material/api>> class Server <<$material/server>> User --> API API --> Server @enduml
<<$material/X>> 用具体的图标作为 stereotype。
AWS / Azure / GCP 图标 1 2 3 4 5 6 7 8 9 10 11 12 13 14 @startuml !include <aws/common> !include <aws/Compute/EC2> !include <aws/Database/RDS> !include <aws/Networking/ELB> class WebServer <<$aws_compute_ec2>> class DB <<$aws_database_rds>> class LoadBalancer <<$aws_networking_elb>> WebServer --> DB LoadBalancer --> WebServer @enduml
实战:完整云架构图 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 @startuml !include <aws/common> !include <aws/Compute/EC2> !include <aws/Database/RDS> !include <aws/Networking/ELB> !include <aws/Storage/S3> !include <aws/Security/Cognito> actor 用户 <<$material/account>> cloud "VPC" { LoadBalancer <<$aws_networking_elb>> EC2 <<$aws_compute_ec2>> RDS <<$aws_database_rds>> } S3 <<$aws_storage_s3>> Cognito <<$aws_security_cognito>> 用户 --> Cognito : 认证 用户 --> LoadBalancer : HTTPS LoadBalancer --> EC2 : HTTP EC2 --> RDS : SQL EC2 --> S3 : Static assets @enduml
自定义 stereotype 1 2 3 4 5 6 7 8 @startuml skinparam stereotypeCBackgroundColor #FAFAFA class OrderService <<(Q, #A31F34) Service>> class PaymentService <<(P, #20A464) Service>> class UserController <<(C, #F4B40A) Controller>> @enduml
<<(X, #color) Label>> 自定义 stereotype 颜色。
完整实战:可复用的样式 + 数据驱动图 1 2 3 4 5 6 7 8 9 # _include/puml/style.puml !define COLOR_PRIMARY #A31F34 !define COLOR_BG #FAFAFA skinparam { BackgroundColor %COLOR_BG BorderColor %COLOR_PRIMARY ArrowColor %COLOR_PRIMARY }
1 2 # _include/puml/icons.puml !include <material/common>
1 2 3 4 5 6 7 8 9 10 @startuml !include _include/puml/style.puml !include _include/puml/icons.puml class OrderService <<$material/server>> class PaymentService <<$material/server>> OrderService --> PaymentService @enduml
CI 渲染:
1 2 3 4 - name: Render diagrams run: | # !include 用的是相对路径时,cd 到 source/ find source -name '*.puml' | xargs -I {} java -jar plantuml.jar -tpng {}
反模式 1. 预处理函数逻辑复杂 1 2 3 4 5 6 7 8 9 !function $calc($a, $b) !if ($a > 100 && $b > 50) !return $a * $b + 100 !elseif ($a < 0) !return 0 !else !return $a + $b !endif !endfunction
预处理函数逻辑一长就难调试,简单的颜色选择 / 文本替换用 !define 就够。
2. !include 远程 URL 1 !includeurl https://raw.githubusercontent.com/.../C4_Container.puml
CI 一般会因网络问题失败。本地 vendor。
3. 滥用图标 1 2 3 4 5 6 7 8 9 10 11 class A class B class C class D class E <<$material/server>> <<$material/database>> <<$material/api>> <<$material/globe_network>> <<$material/storage>> @enduml
类多于图标库能覆盖的范围,图标就重复,反而看起来更乱。
评审 checklist 预处理
图标
一句话总结 预处理 + 图标库 = PlantUML 从「画一遍样式」升级到「模板驱动」。抽共用样式 + 选好图标库 + 写个 render 脚本,整套文档图就一气呵成。