Golang如何将Excel行数据转换为结构体

Golang如何将Excel行数据转换为结构体

func Upload_menus(ctx *gin.Context) error {

	type System_menus struct {
		Menuid            string `json:"menuid"`
		Parent_order      string `json:"parent_order"`
		Parent_name       string `json:"parent_name"`
		Parent_icon       string `json:"parent_icon"`
		Parent_url        string `json:"parent_url"`
		Parent_badge      string `json:"parent_badge"`
		Childlevel1_order string `json:"childlevel1_order"`
		Childlevel1_name  string `json:"childlevel1_name"`
		Childlevel1_url   string `json:"childlevel1_url"`
		Childlevel1_icon  string `json:"childlevel1_icon"`
		Childlevel1_badge string `json:"childlevel1_badge"`
		Childlevel2_order string `json:"childlevel2_order"`
		Childlevel2_name  string `json:"childlevel2_name"`
		Childlevel2_url   string `json:"childlevel2_url"`
		Childlevel2_icon  string `json:"childlevel2_icon"`
		Childlevel2_badge string `json:"childlevel2_badge"`
	}

	var (
		err         error
		systemmenus []System_menus
	)

	_filename, err := ctx.FormFile("file")
	if err != nil {
		return err
	}

	sExcelfile := _filename.Filename
	sExcelfile = filepath.Join(easyglobal.APPPATH, "EXCEL", sExcelfile)
	easyglobal.Excel, err = excelize.OpenFile(sExcelfile)
	if err != nil {
		return err
	}

	// Get all the excel_rows in the Sheet1.
	excel_rows, err := easyglobal.Excel.GetRows("MENUS")
	if err != nil {
		return err
	}

	for nIndex, Rows := range excel_rows {

		if nIndex < 6 {
			continue
		}

		if len(Rows) <= 0 {
			continue
		}

		if len(Rows[0]) <= 0 {
			continue
		}

		var (
			systemmenu System_menus
		)

		x := []byte(Rows)

		err = json.Unmarshal(x, &systemmenu)
		if err != nil {
			return errors.New("Error here : " + err.Error())
		}

		systemmenus = append(systemmenus, systemmenu)
	}

	if len(systemmenus) > 0 {
		tx, err := easyglobal.Db.Beginx()
		if err != nil {
			return err
		}
		defer func(tx *sqlx.Tx) {
			if err != nil {
				_ = tx.Rollback()
			} else {
				_ = tx.Commit()
			}
		}(tx)

		_, err = tx.NamedExec(appquery.IU_systemmenu, systemmenus)
		if err != nil {
			return err
		}

	}
	return nil
}

我遇到了错误 “x := []byte(Rows)”,我无法将 []string 转换为 []byte。

我正在尝试将行数据转换到结构体中。


更多关于Golang如何将Excel行数据转换为结构体的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

根据Excelize文档,GetRows返回[][]string,因此你需要使用strings包中的join或Builder将Rows转换为字符串。

func main() {
    fmt.Println("hello world")
}

更多关于Golang如何将Excel行数据转换为结构体的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


问题出在 Rows[]string 类型,不能直接转换为 []byte。Excel 行数据需要手动映射到结构体字段。以下是修正后的代码:

func Upload_menus(ctx *gin.Context) error {
    type System_menus struct {
        Menuid            string `json:"menuid"`
        Parent_order      string `json:"parent_order"`
        Parent_name       string `json:"parent_name"`
        Parent_icon       string `json:"parent_icon"`
        Parent_url        string `json:"parent_url"`
        Parent_badge      string `json:"parent_badge"`
        Childlevel1_order string `json:"childlevel1_order"`
        Childlevel1_name  string `json:"childlevel1_name"`
        Childlevel1_url   string `json:"childlevel1_url"`
        Childlevel1_icon  string `json:"childlevel1_icon"`
        Childlevel1_badge string `json:"childlevel1_badge"`
        Childlevel2_order string `json:"childlevel2_order"`
        Childlevel2_name  string `json:"childlevel2_name"`
        Childlevel2_url   string `json:"childlevel2_url"`
        Childlevel2_icon  string `json:"childlevel2_icon"`
        Childlevel2_badge string `json:"childlevel2_badge"`
    }

    var (
        err         error
        systemmenus []System_menus
    )

    _filename, err := ctx.FormFile("file")
    if err != nil {
        return err
    }

    sExcelfile := _filename.Filename
    sExcelfile = filepath.Join(easyglobal.APPPATH, "EXCEL", sExcelfile)
    easyglobal.Excel, err = excelize.OpenFile(sExcelfile)
    if err != nil {
        return err
    }

    excel_rows, err := easyglobal.Excel.GetRows("MENUS")
    if err != nil {
        return err
    }

    for nIndex, rows := range excel_rows {
        if nIndex < 6 {
            continue
        }

        if len(rows) <= 0 {
            continue
        }

        if len(rows[0]) <= 0 {
            continue
        }

        // 手动映射Excel列到结构体字段
        systemmenu := System_menus{
            Menuid:            safeGet(rows, 0),
            Parent_order:      safeGet(rows, 1),
            Parent_name:       safeGet(rows, 2),
            Parent_icon:       safeGet(rows, 3),
            Parent_url:        safeGet(rows, 4),
            Parent_badge:      safeGet(rows, 5),
            Childlevel1_order: safeGet(rows, 6),
            Childlevel1_name:  safeGet(rows, 7),
            Childlevel1_url:   safeGet(rows, 8),
            Childlevel1_icon:  safeGet(rows, 9),
            Childlevel1_badge: safeGet(rows, 10),
            Childlevel2_order: safeGet(rows, 11),
            Childlevel2_name:  safeGet(rows, 12),
            Childlevel2_url:   safeGet(rows, 13),
            Childlevel2_icon:  safeGet(rows, 14),
            Childlevel2_badge: safeGet(rows, 15),
        }

        systemmenus = append(systemmenus, systemmenu)
    }

    if len(systemmenus) > 0 {
        tx, err := easyglobal.Db.Beginx()
        if err != nil {
            return err
        }
        defer func(tx *sqlx.Tx) {
            if err != nil {
                _ = tx.Rollback()
            } else {
                _ = tx.Commit()
            }
        }(tx)

        _, err = tx.NamedExec(appquery.IU_systemmenu, systemmenus)
        if err != nil {
            return err
        }
    }
    return nil
}

// 安全获取切片元素,避免索引越界
func safeGet(slice []string, index int) string {
    if index < len(slice) {
        return slice[index]
    }
    return ""
}

如果需要更通用的解决方案,可以使用反射和结构体标签:

func excelToStruct(rows []string, target interface{}) error {
    v := reflect.ValueOf(target).Elem()
    t := v.Type()

    for i := 0; i < v.NumField(); i++ {
        field := v.Field(i)
        if i < len(rows) && field.CanSet() && field.Kind() == reflect.String {
            field.SetString(rows[i])
        }
    }
    return nil
}

// 使用示例
for nIndex, rows := range excel_rows {
    if nIndex < 6 {
        continue
    }

    var systemmenu System_menus
    err := excelToStruct(rows, &systemmenu)
    if err != nil {
        return err
    }
    systemmenus = append(systemmenus, systemmenu)
}

或者使用第三方库如 github.com/tealeg/xlsxgithub.com/qax-os/excelize 的流式读取功能:

// 使用excelize的流式读取
rows, err := easyglobal.Excel.Rows("MENUS")
if err != nil {
    return err
}

rowIndex := 0
for rows.Next() {
    rowIndex++
    if rowIndex <= 6 {
        continue
    }
    
    cols, err := rows.Columns()
    if err != nil {
        return err
    }
    
    systemmenu := System_menus{
        Menuid:            safeGet(cols, 0),
        // ... 其他字段映射
    }
    systemmenus = append(systemmenus, systemmenu)
}
回到顶部