本文讲解如何使用 Go 语言(配合 tealeg/xlsx 库)从 Excel 表格的指定列(如第 4 和第 6 列)提取数据,并将其组合成单个结构化 JSON 对象,而非为每个单元格生成独立 JSON,解决常见“多单元格→单 JSON”的映射逻辑错误。
本文讲解如何使用 go 语言(配合 tealeg/xlsx 库)从 excel 表格的指定列(如第 4 和第 6 列)提取数据,并将其组合成单个结构化 json 对象,而非为每个单元格生成独立 json,解决常见“多单元格→单 json”的映射逻辑错误。
在您原始代码中,每次遍历到满足条件的单元格(x == 3 || x == 5)时,都会新建一个 map[string]string 并立即序列化输出——这导致每个单元格各自生成一个 JSON 对象(如 {"d_name":"cell1","name":"cell1"}),而实际需求是将同一行中不同列的值组合进同一个 JSON 对象,例如将第 4 列(索引 3)作为 "foo" 字段、第 6 列(索引 5)作为 "bar" 字段,最终输出 {"foo":"cell1","bar":"cell2"}。
关键在于:JSON 构建应发生在行级(row-level)而非单元格级(cell-level)。需在遍历一行的过程中收集所需列的值,再统一构造并序列化目标结构。
以下是修正后的核心逻辑(已适配您的预期输出格式):
把记录数组导出为带样式的 Excel(xlsx) 或带 BOM 的 CSV。支持列配置(表头/宽度/顺序)、表头冻结首行、斑马纹、布尔值转「是/否」、数组换行、CSV 中文防乱码。零依赖。触发词:导出 Excel、导出 CSV、记录转表格、列配置导出、数据导出、表格美化、JSON 转表格。
for _, sheet := range xlFile.Sheets {
for _, row := range sheet.Rows {
// 初始化一个 map 来承载本行的多个字段
rowData := make(map[string]string)
for x, cell := range row.Cells {
switch x {
case 3: // 第 4 列(0-based 索引),对应 "foo"
rowData["foo"] = cell.String()
case 5: // 第 6 列(0-based 索引),对应 "bar"
rowData["bar"] = cell.String()
}
}
// ✅ 只在处理完该行所有目标列后,统一 Marshal
if len(rowData) > 0 { // 防止空行输出 {}
jsonData, err := json.Marshal(rowData)
if err != nil {
fmt.Printf("JSON marshaling error: %v\n", err)
continue
}
fmt.Println(string(jsonData))
}
}
}
⚠️ 注意事项:
- x == 3 和 x == 5 是基于 0 起始索引,对应 Excel 中的 D 列和 F 列,请根据实际列位置调整;
- 原答案中使用 []map[string]string{}(切片)会生成 JSON 数组(如 [{"d_name":"c1","name":"c1"},{"d_name":"c2","name":"c2"}]),不符合您期望的单对象结构,因此本文采用 map[string]string 作为单行容器;
- 若需处理多行并生成 JSON 数组(如 [{"foo":"r1c1","bar":"r1c2"},{"foo":"r2c1","bar":"r2c2"}]),则应在外层定义 var allRows []map[string]string,并在每行处理完毕后执行 allRows = append(allRows, rowData),最后统一 json.Marshal(allRows);
- 务必检查 json.Marshal 的返回错误,避免静默失败;
- 空单元格会返回空字符串,如需跳过或设默认值,可在赋值前添加 if cell.String() != "" 判断。
通过将数据收集与序列化解耦,并明确作用域(按行聚合),即可精准实现“多单元格→单 JSON 对象”的转换目标。










