用低代码搭了一套证书模板系统
在用 Puppeteer + Node 做证书截图服务里,我们把证书做成「背景图 + 定位」的 HTML 页,由服务端统一截图产出图片,解决了用户设备差异导致的文字错乱问题。随着业务完善,班级、考试活动、训练营等场景都接入了证书能力,证书类型也从单一的「成绩单」扩展到结业证、优秀学员、活动参与证明等;同时运营和用户提出了自定义证书样式的需求——换背景、改排版、加 Logo、调字体颜色等。若每次改版都靠开发写 HTML 再发版,节奏会跟不上。于是我们用低代码搭建了一套证书模板系统:在后台通过可视化或表单配置模板(背景、占位区域、样式),保存为可复用的模板;渲染时根据「模板 + 数据」生成证书页,仍走现有 Puppeteer 截图服务出图。本文记录这套系统的设计和实现思路。
一、业务诉求
- 证书场景增多:班级结业、单次考试、系列活动、训练营结业等,每种都可能需要不同版式的证书。
- 样式需可配置:背景图、标题/副标题文案、姓名/成绩/日期等占位区域的位置、字体、字号、颜色,以及是否展示 Logo、二维码等,希望由运营或老师在后台配置,而不是改代码。
- 产出方式不变:最终仍要得到一张图片,用于下载、打印、推送,即继续使用现有 Puppeteer 截图服务,模板系统只负责产出「证书页 HTML」或「证书页 URL」,再由截图服务渲染成图。
因此目标很明确:做一套低代码的证书模板配置与渲染能力,与现有截图服务解耦但无缝对接。
二、整体思路
- 模板:一份配置描述「证书长什么样」——背景图 URL、画布尺寸,以及多个占位块(如姓名、成绩、日期、自定义文案),每个占位块包含位置(如绝对坐标或相对布局)、字体样式、数据字段绑定(对应接口里的哪个字段)。
- 低代码配置:在后台提供模板编辑器。可以是表单式(选背景、填各区块的 x/y/宽高、选字体字号颜色、绑定字段),也可以是简单拖拽(在画布上拖拽文本框/图片块并设置属性)。模板保存为 JSON 或其它 DSL,落库或落文件。
- 渲染引擎:根据「模板 JSON + 业务数据」生成证书页 HTML(或带参数的证书页 URL)。HTML 内仍是「背景图 + 绝对定位的 div」,只是结构和样式由模板驱动,而不是写死在代码里。
- 与截图服务对接:渲染引擎产出的 HTML 或 URL 交给现有 Puppeteer 截图服务(例如
POST /cert/screenshot传入 html 或 templateId + data),得到图片。这样证书样式迭代无需动截图服务代码。
三、模板数据结构(示例)
模板可以用 JSON 描述,例如:
{
"id": "cert-exam-v2",
"name": "考试成绩证书",
"width": 800,
"height": 600,
"background": "https://cdn.example.com/cert-bg-exam.png",
"blocks": [
{
"id": "title",
"type": "text",
"content": "成绩证书",
"x": 50,
"y": 40,
"fontSize": 28,
"fontWeight": "bold",
"color": "#333"
},
{
"id": "name",
"type": "text",
"field": "userName",
"x": 200,
"y": 240,
"fontSize": 24,
"color": "#000"
},
{
"id": "score",
"type": "text",
"field": "score",
"x": 520,
"y": 240,
"fontSize": 24,
"color": "#000"
},
{
"id": "date",
"type": "text",
"field": "issueDate",
"x": 400,
"y": 520,
"fontSize": 16,
"color": "#666"
}
]
}
field表示该块内容来自业务数据的字段;无field的块使用固定content(如标题文案)。- 渲染时遍历
blocks,用数据里的userName、score、issueDate等填进去,再生成内联样式或 class,输出 HTML。
四、模板编辑器(低代码层)
- 列表:展示已有模板(名称、缩略图、关联场景),支持新建、复制、删除。
- 编辑:
- 画布区:按模板的 width/height 展示背景图,上面叠一层占位块;占位块可拖拽调整位置,右侧面板可编辑当前块的 x/y、宽高、字体、颜色、绑定字段。
- 或简化为表单:上传背景、填各区块的坐标与样式、下拉选择绑定字段,适合对排版精度要求不极致的场景。
- 预览:用一份测试数据在画布或新开页预览证书效果,确认后再保存模板。
- 保存:将模板序列化为 JSON 写入后端,并生成唯一 templateId,供渲染与截图时使用。
这样运营/老师就可以在后台「选图 + 摆块 + 绑字段」,无需碰代码。
五、渲染引擎与对接截图服务
- 输入:templateId(或模板 JSON)+ 业务数据(如
{ userName, score, issueDate })。 - 逻辑:根据模板生成证书页 HTML——根节点尺寸和背景图来自模板,每个 block 转成一个绝对定位的 div,文本内容来自
content或data[block.field],样式来自 block 的 fontSize、color 等。 - 输出:完整 HTML 字符串(或可访问的证书页 URL)。
- 对接:现有截图接口扩展为支持「传入 html」或「传入 templateId + data,由服务端先调渲染引擎再截图」。证书展示/下载流程不变,仍是一次请求拿到一张图。
班级、考试、活动等业务只需在发证时传入「模板 ID + 数据」,即可拿到统一风格的证书图片;新证书类型只需在低代码后台配一个新模板即可上线。
六、小结
- 业务完善后,班级、考试活动等场景出现多种证书类型和自定义证书样式需求,纯靠开发写 HTML 发版难以支撑。
- 通过低代码搭建证书模板系统:模板用 JSON 描述背景与占位块(位置、样式、数据绑定),后台提供模板编辑器(表单或简单拖拽),渲染引擎根据「模板 + 数据」生成证书页 HTML,再与现有 Puppeteer 截图服务对接产出图片。
- 运营/用户可自助配置新证书样式并复用,新证书类型无需发版即可上线,证书产出仍保持「服务端统一渲染、输出图片」的稳定体验。
提示 模板更新后,已生成的证书不会自动变更;若希望历史已发放的证书也采用新样式,需在业务侧提供「是否对历史数据重新生成并覆盖已有证书」的选项,由运营或用户选择是否执行。