如何在Golang中实现动态JSON转CSV?
如何在Golang中实现动态JSON转CSV?
处理动态JSON(字段不固定)转CSV的核心是先收集所有可能的字段作为表头,再逐行匹配字段值输出。以下是基于Go标准库的实现方案,无需额外依赖:
核心思路
- 将动态JSON解析为
[]map[string]interface{},适配任意键值对结构 - 遍历所有JSON对象,收集所有唯一字段作为CSV表头
- 按表头顺序提取每个对象的对应值,缺失字段留空,最终写入CSV文件
完整代码示例
package main import ( "encoding/csv" "encoding/json" "fmt" "os" "sort" ) func main() { // 示例动态JSON输入 dynamicJSON := `[ {"name": "Alice", "age": 30, "city": "New York"}, {"name": "Bob", "age": 25, "country": "Canada"}, {"name": "Charlie", "city": "London", "email": "charlie@example.com"} ]` // 解析JSON为动态键值对数组 var data []map[string]interface{} if err := json.Unmarshal([]byte(dynamicJSON), &data); err != nil { fmt.Printf("JSON解析失败: %v\n", err) return } // 收集所有唯一字段 columnSet := make(map[string]bool) for _, item := range data { for key := range item { columnSet[key] = true } } // 转换为有序表头(可选,保证输出列顺序稳定) header := make([]string, 0, len(columnSet)) for key := range columnSet { header = append(header, key) } sort.Strings(header) // 创建并写入CSV文件 file, err := os.Create("output.csv") if err != nil { fmt.Printf("文件创建失败: %v\n", err) return } defer file.Close() writer := csv.NewWriter(file) defer writer.Flush() // 写入表头 if err := writer.Write(header); err != nil { fmt.Printf("表头写入失败: %v\n", err) return } // 逐行写入数据 for _, item := range data { row := make([]string, len(header)) for i, col := range header { val, exists := item[col] if !exists { row[i] = "" continue } // 根据值类型转换为字符串 switch v := val.(type) { case string: row[i] = v case float64: row[i] = fmt.Sprintf("%v", v) case bool: row[i] = fmt.Sprintf("%t", v) default: // 嵌套结构转为JSON字符串 nestedJSON, _ := json.Marshal(v) row[i] = string(nestedJSON) } } if err := writer.Write(row); err != nil { fmt.Printf("行写入失败: %v\n", err) return } } fmt.Println("动态JSON转CSV完成") }
关键细节说明
- 动态解析:使用
[]map[string]interface{}接收JSON数据,适配任意字段组合 - 字段收集:通过遍历所有对象的键,确保表头包含所有可能出现的字段
- 类型处理:针对JSON的常见类型(字符串、数字、布尔、嵌套结构)做转换,保证CSV输出格式统一
- 大文件优化:如果处理超大JSON文件,建议使用
json.Decoder流式解析,避免一次性加载全部数据到内存
内容的提问来源于stack exchange,提问作者ORHAN ERDAY
相关产品推荐
相关产品推荐

