【问题标题】:Writing multiple columns in a csv file using golang使用 golang 在 csv 文件中写入多列
【发布时间】:2022-10-20 06:57:47
【问题描述】:

我正在尝试编写一个 CSV 文件,我可以有 1 到 n 列。目前我的数据是正确写入的,只是它们都写在同一列上。

我想要这样的东西:

名称|描述|生产商
名称 1|desc1|假
名称2|描述2|真
名称3|desc3|假

这是我的代码,开关的一小部分:

    case "companies":
                var respToolCompanies entrepriseTool.CompaniesResponse
                if jsonErr := json.Unmarshal(resByt, &respToolCompanies); jsonErr != nil {
                    log.Fatalf("unmarshal: %s", jsonErr)
                }
                for _, mapping := range mappings {
                    writeHeader(csvwriter, mapping)

                    for _, company := range respToolCompanies.Companies {
                        writeDataAccordinglyToFieldType(mapping, company, csvwriter)
                    }
                    csvwriter.Flush()
                }

writeDataAccordinglyToFieldType 函数:

func writeDataAccordinglyToFieldType(mapping ExportmappingsModel, entities interface{}, csvwriter *csv.Writer) {
    switch mapping.SourceColType.String {
    case "string":
        field := extractFieldValue(entities, mapping)
        writeFieldToBuffer(csvwriter, field.String())
    case "number":
        field := extractFieldValue(entities, mapping)
        valInt := field.Int()
        str := strconv.Itoa(int(valInt))
        writeFieldToBuffer(csvwriter, str)
    case "bool":
        field := extractFieldValue(entities, mapping)
        var boolVal string
        if field.Bool() {
            boolVal = "true"
        } else {
            boolVal = "false"
        }
        writeFieldToBuffer(csvwriter, boolVal)
    }
}

我在哪里写数据:

func writeFieldToBuffer(csvwriter *csv.Writer, field string) {
    err := csvwriter.Write([]string{field})
    if err != nil {
        log.Println("Unable to write a line inside the file")
    }
}

【问题讨论】:

  • Neha的回答有帮助吗?如果没有,您会包含 JSON 的示例吗?另外,当你说你有“n列”时,这是什么意思?您是否提前知道需要将多少列写入 CSV? mappings var 让我觉得您已经知道预期哪些列以及它们将是什么类型。

标签: csv go


【解决方案1】:

csv.Write 仅当您的字符串切片有多个元素时才会写入不同的列。目前您正在逐个写入每个字段并使用一次只有一条记录的切片

我并不是说您必须传递分隔符。而是一次填充字符串切片,以便 csv.Write 自动迭代切片并将每个新元素写入新列中。 .所以改变你的逻辑来改变

       err := csvwriter.Write([]string{field})

像这样:在此处输入代码

  record := []string {"name1" ,"desc1","false"}
   if err := csvwriter.Write(record); err != nil {
          log.Fatalln("error writing record to file", err)
         }

或者您可以使用二维切片填充整个内容,然后在最后写入

   records := [][]string {{"name1" ,"desc1","false"},{"name2" 
   ,"desc2","false"}}
     if err := csvwriter.WriteAll(records); err != nil {
            log.Fatalln("error writing record to file", err)
           }

【讨论】:

    【解决方案2】:

    首先要做的事情:Go 的 csv Writer 写了一个记录, 一条记录是一段字符串。查看文档中的示例:

    records := [][]string{
        {"first_name", "last_name", "username"},
        {"Rob", "Pike", "rob"},
        {"Ken", "Thompson", "ken"},
        {"Robert", "Griesemer", "gri"},
    }
    
    w := csv.NewWriter(os.Stdout)
    
    for _, record := range records {
        if err := w.Write(record); err != nil {
            log.Fatalln("error writing record to csv:", err)
        }
    }
    

    我们可以看到我们是逐行写入 CSV 文件,而不是逐列。因此,您提出的任何解决方案都必须包括整行当你调用 writer.Write(...) 时。

    对于您的问题的具体细节——将 JSON 解码为某个结构,然后将该结构写入 CSV——您是否查看过 Gocarina 的 gocsv 包?它会减少(我想象的)你的问题,如下所示:

    import (
        "encoding/json"
        "os"
    
        "github.com/gocarina/gocsv"
    )
    
    type company struct {
        Name        string `json:"name"        csv:"Name"`
        Description string `json:"description" csv:"Description"`
        Producer    bool   `json:"producer"    csv:"Producer"`
        Employees   int    `json:"employees"   csv:"Employees"`
    }
    
    var blob = `[
        { "name": "Foo To You", "description": "Selling Foo since before the dinosaurs", "producer": false, "employees":  7 },
        { "name": "Bar Mfg.",   "description": "Best makers of Bar, bar none",           "producer": true,  "employees": 12 }
    ]`
    
    func main() {
        var companies []company
        json.Unmarshal([]byte(blob), &companies)
        gocsv.Marshal(companies, os.Stdout)
    }
    

    生成此 CSV(标记为表格):

    | Name       | Description                            | Producer | Employees |
    |------------|----------------------------------------|----------|-----------|
    | Foo To You | Selling Foo since before the dinosaurs | false    | 7         |
    | Bar Mfg.   | Best makers of Bar, bar none           | true     | 12        |
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-05
      • 2018-09-22
      • 1970-01-01
      • 2022-01-28
      • 2017-09-27
      • 1970-01-01
      • 2018-04-27
      • 1970-01-01
      相关资源
      最近更新 更多