duanlan3598 2017-06-10 13:25
浏览 242

使用GO语言以CSV格式写入/保存数据

I am trying to write Student Marks to a csv file in GO .

It is printing the desired 10 result per page with Println but is saving only the last value (not all 10) in csv .

This is what I am doing

  1. Visitor visits studentmarks.com/page=1 Marks for 10 students are displayed and it is also saved in CSV

  2. Visitor clicks next page and he is navigated to studentmarks.com/page=2 Marks for another 10 students are displayed and it is also saved in subsequent column/rows in the CSV

and so on

fmt.Fprintf(w, KeyTemplate, key.fname, key.marks, key.lname ) is working fine and displays all 10 results per page but I am unable to save all 10 results in the CSV (with my current code, only the last result is saved).

Here is my snippet of the code that is responsible for printing and saving the results.

func PageRequest(w http.ResponseWriter, r *http.Request) {
    // Default page number is 1
    if len(r.URL.Path) <= 1 {
        r.URL.Path = "/1"
    }

    // Page number is not negative or 0
    page.Abs(page)
    if page.Cmp(one) == -1 {
        page.SetInt64(1)
    }



    // Page header
    fmt.Fprintf(w, PageHeader, pages, previous, next)

    // Marks for UID
    UID, length := compute(start)
    for i := 0; i < length; i++ {
        key := UID[i]


        fmt.Fprintf(w, key.fname, key.marks, key.lname, key.remarks)


      // Save in csv

 csvfile, err := os.Create("marks.csv")
          if err != nil {
                  fmt.Println("Error:", err)
                  return
          }
          defer csvfile.Close()

          records := [][]string{{key.fname, key.marks, key.lname, , key.remarks}}

          writer := csv.NewWriter(csvfile)
          for _, record := range records {
                  err := writer.Write(record)
                  if err != nil {
                          fmt.Println("Error:", err)
                          return
                  }
          }
          writer.Flush()


    // Page Footer
    fmt.Fprintf(w, PageFooter, previous, next)
}

How can I print and save (in csv) all the 10 results using go language?

  • 写回答

1条回答 默认 最新

  • duankui3838 2017-06-10 16:09
    关注

    The basic problem is that you are calling os.Create. The documentation for os.Create says

    Create creates the named file with mode 0666 (before umask), truncating it if it already exists. If successful, methods on the returned File can be used for I/O; the associated file descriptor has mode O_RDWR. If there is an error, it will be of type *PathError.

    So each call to os.Create will remove all content from the file you passed. Instead what you want is probably os.OpenFile with the os.O_CREATE, os.O_WRONLY and os.O_APPEND flags. This will make sure that the file will be created, if it doesn't exists, but won't truncate it.

    But there is another problem in your code. You are calling defer csvfile.Close() inside the loop. A deferred function will only be executed once the function returns and not after the loop iteration. This can lead to problems, especially since you are opening the same file over and over again.

    Instead you should open the file once before the loop so that you only need to close it once. Like this:

    package main
    
    import (
        "encoding/csv"
        "fmt"
        "net/http"
        "os"
    )
    
    func PageRequest(w http.ResponseWriter, r *http.Request) {
        // Default page number is 1
        if len(r.URL.Path) <= 1 {
            r.URL.Path = "/1"
        }
    
        // Page number is not negative or 0
        page.Abs(page)
        if page.Cmp(one) == -1 {
            page.SetInt64(1)
        }
    
        // Page header
        fmt.Fprintf(w, PageHeader, pages, previous, next)
    
        // Save in csv
        csvfile, err := os.OpenFile("marks.csv", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
        if err != nil {
            fmt.Println("Error:", err)
            return
        }
        defer csvfile.Close()
    
        writer := csv.NewWriter(csvfile)
        defer writer.Flush()
    
        // Marks for UID
        UID, length := compute(start)
        for i := 0; i < length; i++ {
            key := UID[i]
    
            fmt.Fprintf(w, key.fname, key.marks, key.lname, key.remarks)
    
            records := [][]string{{key.fname, key.marks, key.lname, key.remarks}}
    
            for _, record := range records {
                err := writer.Write(record)
                if err != nil {
                    fmt.Println("Error:", err)
                    return
                }
            }
        }
    
        // Page Footer
        fmt.Fprintf(w, PageFooter, previous, next)
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥16 mybatis的代理对象无法通过@Autowired装填
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂
  • ¥15 wordpress 产品图片 GIF 没法显示
  • ¥15 求三国群英传pl国战时间的修改方法
  • ¥15 matlab代码代写,需写出详细代码,代价私
  • ¥15 ROS系统搭建请教(跨境电商用途)