|
package main |
|
|
|
import ( |
|
"fmt" |
|
"reflect" |
|
) |
|
|
|
type meta struct { |
|
Lang string `xlsx:"Язык"` |
|
Gov string `xlsx:"Гражданство"` |
|
} |
|
type user struct { |
|
Name string `xlsx:"Имя"` |
|
Meta meta |
|
Age age `xlsx:"Возвраст"` |
|
} |
|
|
|
type age uint16 |
|
|
|
func main() { |
|
u1 := user{Name: "Max", Age: 14, Meta: meta{Lang: "Russian", Gov: "Russian"}} |
|
u2 := user{Name: "Alex", Age: 24, Meta: meta{Lang: "Eng", Gov: "USA"}} |
|
|
|
users := []user{u1, u2} |
|
headers := GetHeaders(&users, `xlsx`) |
|
fmt.Println(headers) |
|
} |
|
|
|
// GetHeaders - geat headers to slice from interface |
|
func GetHeaders(i interface{}, tag string) (headers []string) { |
|
var E reflect.Type |
|
T := reflect.TypeOf(i) |
|
switch T.Kind() { |
|
case reflect.Ptr: |
|
E = T.Elem() |
|
default: |
|
E = T |
|
} |
|
headers = make([]string, 0) |
|
switch E.Kind() { |
|
case reflect.Slice: |
|
headers = append(headers, getTagFromStruct(oneFromSlice(E), tag)...) |
|
case reflect.Array: |
|
headers = append(headers, getTagFromStruct(oneFromArray(E), tag)...) |
|
case reflect.Struct: |
|
headers = append(headers, getTagFromStruct(E, tag)...) |
|
} |
|
return |
|
} |
|
|
|
func oneFromSlice(T reflect.Type) reflect.Type { |
|
return reflect.MakeSlice(T, 1, 1).Index(0).Type() |
|
} |
|
|
|
func oneFromArray(T reflect.Type) reflect.Type { |
|
return reflect.New(T).Elem().Slice(0, 1).Index(0).Type() |
|
} |
|
|
|
func getTagFromStruct(T reflect.Type, tag string) (headers []string) { |
|
fieldsCount := T.NumField() |
|
headers = make([]string, 0) |
|
for i := 0; i < fieldsCount; i++ { |
|
field := T.Field(i) |
|
switch field.Type.Kind() { |
|
case reflect.Struct: |
|
headers = append(headers, getTagFromStruct(field.Type, tag)...) |
|
} |
|
if t, ok := field.Tag.Lookup(tag); ok { |
|
headers = append(headers, t) |
|
} |
|
} |
|
return |
|
} |