将结构体写入CSV文件

20

如何以一种惯用的 golang 方法将结构体转储到提供的 csv 文件中?我在一个函数内部,我的结构体作为 interface{} 传递:

func decode_and_csv(my_response *http.Response, my_struct interface{})

为什么要使用interface{}? 读取来自JSON的数据时,可能会返回几个不同的结构体,因此尝试编写一个通用的函数。

这是我的类型示例:

type Location []struct {
    Name                   string `json: "Name"`
    Region                 string `json: "Region"`
    Type                   string `json: "Type"`
}
1个回答

36

如果您使用具体类型,将会更容易。您可能需要使用encoding/csv包,以下是一个相关示例;https://golang.org/pkg/encoding/csv/#example_Writer

如您所见,Write方法需要一个[]string,因此您需要提供一个帮助方法或者反射my_struct以生成它。个人而言,我更喜欢第一种方法,但这取决于您的需求。如果您选择第二条路,可以获取结构体上的所有字段并将它们用作列标题,然后迭代字段获取每个字段的值,在循环中使用append将它们添加到[]string中,然后在循环外部将其传递给Write

对于第一种选项,我会在每种类型上定义一个ToSlice或类似的方法,然后创建一个接口调用它CsvAble,该接口要求有ToSlice方法。在您的方法my_struct CsvAble中更改类型,而不是使用空接口,然后只需在my_struct上调用ToSlice并将返回值传递到Write即可。您还可以将其返回列标题(这意味着您将获得一个[][]string并需要迭代外部维度,将每个[]string传递到Write),或者您可以要求另一个方法来满足接口,例如GetHeaders,它将返回一个[]string,该字符串是列标题。如果是这种情况,您的代码将如下所示;

w := csv.NewWriter(os.Stdout)
headers := my_struct.GetHeaders()
values := my_struct.ToSlice()
if err := w.Write(headers); err != nil {
    //write failed do something
}
if err := w.Write(values); err != nil {
    //write failed do something
}

如果那不太清楚,请告诉我,我可以为这两种方法之一提供代码示例。


如果需要,可以使用一个函数来获取头信息。func getHeaders(location Location) (header []string) { e := reflect.ValueOf(&location).Elem() for i := 0; i < e.NumField(); i++ { varName := e.Type().Field(i).Name header = append(header, varName) } return header } - Lock-o-motiffe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接