You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Golang HTML模板将嵌套EmployeeNode渲染为组织架构表格

如何用Golang HTML模板动态生成组织架构表格

我有一个代表公司组织树的EmployeeNode结构体,根节点对应CEO,定义及示例数据如下:

type EmployeeNode struct {
    UserName string  
    Children []*EmployeeNode
}

root := &EmployeeNode{
      UserName: "Bob Wang",
      Children: []*EmployeeNode{
         {
            UserName: "Jim Halpert",
            Children: []*EmployeeNode{
               {UserName: "Brett Wang", Children: nil},
               {UserName: "Ryan Wang", Children: nil},
            },
         },
         {
            UserName: "Michael Wang",
            Children: []*EmployeeNode{
               {UserName: "Annie Wang", Children: nil},
               {UserName: "Jay Wang", Children: nil},
            },
         },
      },
   }

基于该数据,我想动态生成类似下图的HTML组织架构表格:
Org Chart

每个EmployeeNode可包含多个子节点或无子节点,我已经知道如何将结构体传递到HTML模板,但不清楚怎么动态生成表格,求解答!


解决方案:用递归模板实现嵌套渲染

组织树是典型的嵌套结构,Golang HTML模板支持递归调用,刚好适配这个场景。下面是具体实现步骤:

1. 编写HTML模板(含递归逻辑)

创建orgchart.tmpl文件,定义递归模板处理节点渲染,配合CSS实现架构图的视觉效果:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>公司组织架构</title>
    <style>
        .org-table {
            border-collapse: collapse;
            margin: 20px auto;
        }
        .org-node {
            border: 1px solid #333;
            padding: 10px 20px;
            text-align: center;
            background-color: #f5f5f5;
            min-width: 120px;
        }
        .org-child-container td {
            padding: 8px;
            vertical-align: top;
        }
        .connect-line {
            border-top: 1px solid #333;
            height: 10px;
        }
        .vertical-line {
            border-left: 1px solid #333;
            width: 0;
        }
    </style>
</head>
<body>
    <table class="org-table">
        {{template "renderNode" .}}
    </table>

    {{define "renderNode"}}
        <!-- 渲染当前节点 -->
        <tr>
            <td class="org-node" colspan="{{len .Children}}">{{.UserName}}</td>
        </tr>
        <!-- 如果有子节点,递归渲染 -->
        {{if .Children}}
            <!-- 连接父节点和子节点的水平线 -->
            <tr>
                <td class="connect-line" colspan="{{len .Children}}"></td>
            </tr>
            <!-- 渲染子节点行 -->
            <tr class="org-child-container">
                {{range .Children}}
                    <td>
                        <table class="org-table">
                            {{template "renderNode" .}}
                        </table>
                    </td>
                {{end}}
            </tr>
            <!-- 子节点之间的垂直线 -->
            <tr>
                {{range .Children}}
                    <td class="vertical-line"></td>
                {{end}}
            </tr>
        {{end}}
    {{end}}
</body>
</html>

2. Go代码加载并渲染模板

在Go程序中加载模板文件,将根节点数据传入并输出渲染结果:

package main

import (
	"html/template"
	"os"
)

type EmployeeNode struct {
	UserName string
	Children []*EmployeeNode
}

func main() {
	// 构建示例组织树数据
	root := &EmployeeNode{
		UserName: "Bob Wang",
		Children: []*EmployeeNode{
			{
				UserName: "Jim Halpert",
				Children: []*EmployeeNode{
					{UserName: "Brett Wang", Children: nil},
					{UserName: "Ryan Wang", Children: nil},
				},
			},
			{
				UserName: "Michael Wang",
				Children: []*EmployeeNode{
					{UserName: "Annie Wang", Children: nil},
					{UserName: "Jay Wang", Children: nil},
				},
			},
		},
	}

	// 加载模板文件
	tmpl, err := template.ParseFiles("orgchart.tmpl")
	if err != nil {
		panic(err)
	}

	// 渲染模板到标准输出(也可写入文件或HTTP响应)
	err = tmpl.Execute(os.Stdout, root)
	if err != nil {
		panic(err)
	}
}

关键细节说明

  • 递归模板:通过{{define "renderNode"}}定义节点模板,内部再次调用{{template "renderNode" .}}处理子节点,完美适配树形嵌套结构
  • 表格布局:父节点单元格用colspan属性横跨所有子节点宽度,保证布局对齐
  • 视觉连接:通过CSS边框绘制水平线和垂直线,模拟组织架构图的层级连接关系
  • 扩展性:如果需要添加员工职位、邮箱等信息,只需修改EmployeeNode结构体和模板中的节点内容即可

内容的提问来源于stack exchange,提问作者discovering

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 19:39:28