使用场景:
用户上传Excel文件后,转换成[][]string,然后根据结构体的标签,反射到对应字段里。
遇到的问题:
结构体切片(结构体数组)使用反射,与单一结构体不同。
源代码:v.Index(i - 1).Elem.Field(k).SetString(rows[i][j])
报错: Handler crashed with error reflect: call of reflect.Value.Elem on struct Value
修改为:v.Index(i - 1).Field(k).SetString(rows[i][j])
下面是官方文档
// 定义结构体
type TkOrders struct {
CreateTime string `excel:"创建时间"`
OrderId string `excel:"淘宝订单编号" important:"yes"`
PayPrice string `excel:"付款金额" important:"yes"`
ClickTime string `excel:"点击时间"`
PayTime string `excel:"付款时间"`
TbPayTime string `excel:"淘宝付款时间"`
ItemId string `excel:"商品ID"`
ItemTitle string `excel:"商品标题"`
ShopName string `excel:"店铺名称"`
ItemPrice string `excel:"商品单价"`
SonOrderId string `excel:"淘宝子订单号"`
}
type TbSellerOrders struct {
OrderTime string `excel:"订单创建时间|创建时间"`
OrderId string `excel:"订单编号|淘宝订单编号" important:"yes"`
PayPrice string `excel:"买家实际支付金额|付款金额" important:"yes"`
NickName string `excel:"买家会员名"`
Alipay string `excel:"买家支付宝账号"`
AlipayOrderId string `excel:"支付单号"`
Addressee string `excel:"收货人姓名"`
Address string `excel:"收货地址 "`
Phone string `excel:"联系手机"`
ItemId string `excel:"商品ID"`
Title string `excel:"宝贝标题 |商品标题"`
}
//字符串数组转结构体
func ArrStringToStruct(tk interface{}, rows [][]string) (t reflect.Type, err error) {
if len(rows) < 2 {
err = errors.New(2001, "表格为空")
return
}
t = reflect.TypeOf(tk)
v := reflect.ValueOf(tk)
for j, r := range rows[0] {
for k := 0; k < t.Elem().NumField(); k++ {
isBreak := false
tags := strings.Split(t.Elem().Field(k).Tag.Get("excel"), "|")
for _, tag := range tags {
if tag == r {
yes := t.Elem().Field(k).Tag.Get("important") == "yes"
for i := 1; i < len(rows); i++ {
if yes && rows[i][j] == "" {
return nil, fmt.Errorf("第%d行‘%s’缺少数据,无法上传。", i+1, r)
}
// 此处不能用 v.Index(i - 1).Elem().Field(k).SetString(rows[i][j])
v.Index(i - 1).Field(k).SetString(rows[i][j])
}
isBreak = true
break
}
}
if isBreak {
break
}
}
}
return
}
//第一种表格
func (this *Orders) GetTkOrder(){
//从excel文件中获取数据返回 [][]string,error
//rows 第一行为表格标题
rows, err := this.Excel.GetRows()
tk := make([]TkOrders, len(rows)-1)
t, err := ArrStringToStruct(tk, rows)
if err != nil {
return
}
/**处理程序**/
}
//另外一种表格
func (this *Orders) GetTbOrder(){
//从excel文件中获取数据返回 [][]string,error
//rows 第一行为表格标题
rows, err := this.Excel.GetRows()
tb := make([]TbSellerOrders , len(rows)-1)
t, err := ArrStringToStruct(tb, rows)
if err != nil {
return
}
/**处理程序**/
}