看起來挺好的,問題如願解決,可是事實證實對已一個還不成熟的語言或是庫最好仍是先測一下的好。興沖沖的卸了測試例子,成功導出了一個text.csv文件,一切看起來都挺好的,然而打開以後就傻眼了:中文亂碼,這個問題其實比較好理解,golang只支持utf-8,而win中文版默認字符集是GB2312(gbk),這樣看來直接轉碼就好了唄。
因爲以前吃了虧,此次咱們先直接報文件轉下碼試試:直接將以前導出的text.csv另存爲ASCII格式,打開後發現回車換行符丟了,所有變成一行了。這下就鬱悶了,先看下源碼吧:
html
// Writer writes a single CSV record to w along with any necessary quoting. // A record is a slice of strings with each string being one field. func (w *Writer) Write(record []string) (err error) { for n, field := range record { if n > 0 { if _, err = w.w.WriteRune(w.Comma); err != nil { return } } // If we don't have to have a quoted field then just // write out the field and continue to the next field. if !w.fieldNeedsQuotes(field) { if _, err = w.w.WriteString(field); err != nil { return } continue } if err = w.w.WriteByte('"'); err != nil { return } for _, r1 := range field { switch r1 { case '"': _, err = w.w.WriteString(`""`) case '\r': if !w.UseCRLF { err = w.w.WriteByte('\r') } case '\n': if w.UseCRLF { _, err = w.w.WriteString("\r\n") } else { err = w.w.WriteByte('\n') } default: _, err = w.w.WriteRune(r1) } if err != nil { return } } if err = w.w.WriteByte('"'); err != nil { return } } if w.UseCRLF { _, err = w.w.WriteString("\r\n") } else { err = w.w.WriteByte('\n') } return }能夠看到代碼十分簡單,每行就是按照csv的格式寫入文件而已。須要注意的是writer裏邊有一個UserCRLF來指定是否適應回車換行符,默認爲false,問題應該就出在這裏,可是將 UserCRLF設置爲true以後,問題依舊 ,看來是轉碼有問題。
package components import ( "bytes" "errors" iconv "github.com/djimenez/iconv-go" ) /** * 導出處理 */ const ( OUT_ENCODING = "gbk" //輸出編碼 ) /** * 導出csv格式文件,輸出byte數組 * 輸出編碼經過OUT_ENCODING指定 */ func ExportCsv(head []string, data [][]string) (out []byte, err error) { if len(head) == 0 { err = errors.New("ExportCsv Head is nil") return } columnCount := len(head) dataStr := bytes.NewBufferString("") //添加頭 for index, headElem := range head { separate := "," if index == columnCount-1 { separate = "\n" } dataStr.WriteString(headElem + separate) } //添加數據行 for _, dataArray := range data { if len(dataArray) != columnCount { //數據項數小於列數 err = errors.New("ExportCsv data format is error.") } for index, dataElem := range dataArray { separate := "," if index == columnCount-1 { separate = "\n" } dataStr.WriteString(dataElem + separate) } } //處理編碼 out = make([]byte, len(dataStr.Bytes())) iconv.Convert(dataStr.Bytes(), out, "utf-8", OUT_ENCODING) return }測試一下,導出成功,並且沒有亂碼問題。