2017-06-10 16 views
0

我想將學生標記寫入GO中的csv文件。使用GO語言寫入/保存CSV數據

它打印每頁所需的10結果與Println,但只節省CSV的最後一個值(不是所有的10)。

這是我在做什麼

  1. 訪問者訪問顯示studentmarks.com/page=1 標記爲10名學生,它也保存在CSV

  2. 訪問者點擊下頁,他被導航到studentmarks.com/page=2 另外10名學生標記顯示,它也被保存在隨後的列/行的CSV

fmt.Fprintf(w, KeyTemplate, key.fname, key.marks, key.lname)工作正常,並顯示每個網頁10分的結果,但我無法保存所有10個結果中的CSV(我目前的代碼,只有最後的結果被保存)。

這是我負責打印和保存結果的代碼片段。

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) 
} 

如何使用go language打印並保存(在csv中)所有10個結果?

+0

將創建csv文件'marks.csv'的語句,即'csvfile,err ... defer ...'移出'for for循環,例如。調用'compute(start)'之後。 – putu

+0

no沒有幫助,值在(key.fname,key.marks,key.lname,key.remarks)中,由程序生成和打印的值是正確的,唯一的事情是我需要將它成功保存在csv。 – Nancy

+0

可能從我的第一條評論中不太清楚。您需要將語句(6行)'csvfile,err:= os.Create(「marks.csv」)...延遲csvfile.Close()'退出for循環。其他語句(來自'records:= ...')應該保持原樣。 – putu

回答

0

最根本的問題是,你在呼喚os.Create。爲os.Create文檔說

創建創建了模式0666(之前的umask),命名的文件,如果它已經存在截斷它。如果成功,返回文件上的方法可用於I/O;關聯的文件描述符具有模式O_RDWR。如果有錯誤,它將是* PathError類型。

因此,每次調用os.Create都會從您傳遞的文件中刪除所有內容。相反,你想要的可能是os.OpenFileos.O_CREATE,os.O_WRONLYos.O_APPEND標誌。這將確保文件將被創建,如果它不存在,但不會截斷它。

但是在你的代碼中還有另一個問題。您在迴路內呼叫defer csvfile.Close()。延遲函數只會執行一次該函數返回而不是循環迭代之後。這可能會導致問題,尤其是因爲您一遍又一遍地打開同一個文件。

相反,你應該在循環之前打開文件一次,所以你只需要一次關閉它。像這樣:

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) 
} 
+0

將以CSV格式附加結果,我們能否以不同的CSV格式保存每個頁面的結果,如 - 1.)訪問者訪問頁面1 10名學生的標記以CSV格式保存在marks1.csv,2中。)訪問者訪問頁面2標記爲10個學生以CSV格式保存在marks2.csv中,等等... – Nancy