字
字节笔记本
2026年2月22日
Go 结合反射轻松将结构体转换成 Excel
本文介绍如何使用 Go 语言的反射机制结合 tealeg/xlsx 库,轻松将结构体数据转换为 Excel 表格。通过标签(tag)定义表头,利用反射自动提取字段值,实现通用的结构体转 Excel 解决方案。
Excel 中的一些概念
在开始之前,先了解一些 Excel 的基本概念:
- 一个 excel 文件中可以包含多个
sheet,一个sheet可以理解成一个表格 - 表格的每一行称为
Row - 表格的每一行中的任意一个单元格称为
Cell
使用 tealeg 操作 Excel
安装 tealeg
bash
go get github.com/tealeg/xlsx使用 tealeg 新建一个表格
tealeg 提供了傻瓜式 API,主要流程为创建一个 Sheet,在 Sheet 中添加 Row,然后在 Row 中添加每个单元格的值,最终持久化到磁盘。
go
func TestTealeg(t *testing.T) {
excel := xlsx.NewFile()
// 新建一个 sheet
sheet, err := excel.AddSheet("Sheet1")
if err != nil {
t.Fatal(err)
}
// 创建首行
headerRow := sheet.AddRow()
// 设置行高
headerRow.SetHeightCM(0.5)
// 填充行中的单元格
headerRow.AddCell().Value = "姓名"
headerRow.AddCell().Value = "年龄"
valList := [][]string{
{"张三", "13"},
{"李四", "14"},
{"王五", "15"},
}
for _, line := range valList {
row := sheet.AddRow()
row.SetHeightCM(0.5)
for _, v := range line {
row.AddCell().Value = v
}
}
// 持久化到磁盘
if err := excel.Save("username.xlsx"); err != nil {
t.Fatal(err)
}
}执行这个 Test 用例后,在项目的当前文件夹中会出现一个 username.xlsx 的表格。
Go 结合反射将结构体转换成 Excel
实现思路
- 在 Go 的结构体中每个属性打上一个
excel标签 - 利用反射获取标签中的内容,作为表格的 Header
- 利用反射获取 Go 结构体中的属性的值,组成一个 map,key 为从标签中反射获取的值,val 为结构体属性具体的值
- 如果一个 array 或者 slice 中的结构体需要转换成 excel,那么只需要将每个元素转换成 map 作为一行,组成一个
[]map[excelTag]strucVal,然后遍历这个切片,追加到表格中即可
反射获取每个 Struct 中的 Tag
go
func getStructTagList(v interface{}, tag string) []string {
var resList []string
if v == nil {
return resList
}
var item interface{}
switch reflect.TypeOf(v).Kind() {
case reflect.Slice, reflect.Array:
values := reflect.ValueOf(v)
if values.Len() == 0 {
return resList
}
item = values.Index(0).Interface()
case reflect.Struct:
item = reflect.ValueOf(v).Interface()
default:
panic(fmt.Sprintf("type %v not support", reflect.TypeOf(v).Kind()))
}
typeOf := reflect.TypeOf(item)
fieldNum := typeOf.NumField()
for i := 0; i < fieldNum; i++ {
resList = append(resList, typeOf.Field(i).Tag.Get(tag))
}
return resList
}通过反射将结构体的值转换成 map[excelTag]strucVal
go
func getTagValMap(v interface{}, tag string) map[string]string {
resMap := make(map[string]string)
if v == nil {
return resMap
}
typeOf := reflect.TypeOf(v)
fieldNum := typeOf.NumField()
for i := 0; i < fieldNum; i++ {
structField := typeOf.Field(i)
tagValue := structField.Tag.Get(tag)
val := reflect.ValueOf(v).FieldByName(structField.Name)
resMap[tagValue] = fmt.Sprintf("%v", val.Interface())
}
return resMap
}利用反射将 Slice、Array 或 Struct 转换成 []map[excelTag]strucVal
go
func struct2MapTagList(v interface{}, tag string) []map[string]string {
var resList []map[string]string
switch reflect.TypeOf(v).Kind() {
case reflect.Slice, reflect.Array:
values := reflect.ValueOf(v)
for i := 0; i < values.Len(); i++ {
resList = append(resList, getTagValMap(values.Index(i).Interface(), tag))
}
break
case reflect.Struct:
val := reflect.ValueOf(v).Interface()
resList = append(resList, getTagValMap(val, tag))
break
default:
panic(fmt.Sprintf("type %v not support", reflect.TypeOf(v).Kind()))
}
return resList
}通过 tealeg 将 []map[excelTag]strucVal 转换成 Excel
通过上面两步,已经可以将一个结构体、切片或者 list 转换成了一个 []map[excelTag]strucVal 类型的切片,下面我们只需要调用 tealeg 转换成 excel:
go
func Struct2Xlsx(v interface{}) (*xlsx.File, error) {
var tag = "excel"
tagList := getStructTagList(v, tag)
mapTagList := struct2MapTagList(v, tag)
excelFile := xlsx.NewFile()
sheet, err := excelFile.AddSheet("Sheet1")
if err != nil {
return nil, err
}
headerRow := sheet.AddRow()
for _, tagVal := range tagList {
headerRow.SetHeightCM(0.5)
headerRow.AddCell().Value = tagVal
}
for _, mapTagVal := range mapTagList {
row := sheet.AddRow()
for _, tagVal := range tagList {
row.SetHeightCM(0.5)
row.AddCell().Value = mapTagVal[tagVal]
}
}
return excelFile, nil
}运行测试用例验证
go
type Username struct {
Name string `excel:"姓名"`
Age int `excel:"年龄"`
}
func TestStruct2Excet(t *testing.T) {
var data = []Username{
{
Name: "张三",
Age: 13,
},
{
Name: "李四",
Age: 14,
},
{
Name: "王五",
Age: 15,
},
}
excel, err := Struct2Xlsx(data)
if err != nil {
t.Fatal(err)
}
if err := excel.Save("username.xlsx"); err != nil {
t.Fatal(err)
}
}测试运行成功后,会在项目目录创建一个 username.xlsx 的文件,这个文件就是我们的结构体转换成 excel 的结果。
总结
通过本文介绍的方法,你可以:
- 使用结构体标签定义 Excel 表头
- 利用 Go 反射自动提取结构体字段值
- 支持单个结构体、切片、数组等多种数据类型
- 通过 tealeg/xlsx 库生成标准的 Excel 文件
这种方式非常适合需要将数据库查询结果或 API 响应数据导出为 Excel 的场景,代码简洁且易于维护。
分享: