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/xlsx 或 github.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)
}

