iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

0
Software Development

Go繁不及備載系列 第 34

# Day34 Golang 操作CSV檔案

Day34 Golang 操作CSV

CVS 是以逗號,及換行\n分隔的資料格式,
從CSV的英文(Comma-Separated Values)中就能窺出一二。

CSV長的怎樣

用Excel開啟一個CSV檔案
(副檔名要為.csv 而非.xlsx。 xlsx是 Microsoft Office Excel 獨有的格式)
Execl

用記事本開啟一個CSV檔案
原來就長成這樣而已
Notepad++

(也有出現以空白字元\t 或其他字元來做分隔,只要解析時以該字元下去做區隔就行)

讀取 Read CSV

Golang讀檔案時會需要用到絕對路徑
在這邊先取 pwd 當前路徑、再加上 fileName 檔案名稱。

var Pwd string
var FilePath string
var FileName = "test.csv"

func init() {
	Pwd, _ = os.Getwd()
	FilePath = filepath.Join(Pwd, FileName)
}

func Load() {
	file, err := os.OpenFile(FilePath, os.O_RDONLY, 0777) // os.O_RDONLY 表示只讀、0777 表示(owner/group/other)權限
	if err != nil {
		log.Fatalln("找不到CSV檔案路徑:", FilePath, err)
	}

	// read
	r := csv.NewReader(file)
	r.Comma = ','	// 以何種字元作分隔,預設為`,`。所以這裡可拿掉這行
	for {
		record, err := r.Read()
		if err == io.EOF {
			break
		}
		if err != nil {
			log.Fatalln(err)
		}

		var a = record[0]
		var b = record[1]

		fmt.Println(a, b)
	}
}

讀取結果

讀取結果

讀寫權限的常數

os.O_RDONLY 唯讀
os.O_WRONLY 唯寫
os.O_RDWR   讀/寫

詳見官方文檔

寫入 Write CSV

Write寫入單行

func Write() {
	file, err := os.OpenFile(FilePath, os.O_WRONLY, 0777)
	if err != nil {
		log.Fatalln("找不到CSV檔案路徑:", FilePath, err)
	}

	w := csv.NewWriter(file)
	x := []string{"999"}
	w.Write(x)

	w.Flush() // 把在buffer緩存中的所有資料輸出
}

WriteAll寫入多行

	w := csv.NewWriter(file)
	x := [][]string{{"999", "1"}, {"998", "997"}}
	w.WriteAll(x)

	w.Flush() // 把在buffer緩存中的所有資料輸出

寫入的坑

若開啟一個空白檔案寫入,不會有任何問題。
但若開啟已經有資料的CSV,再寫入的話會發生炸裂

已有的原始資料
原始資料

如果寫入以下一行資料

	w := csv.NewWriter(file)
	x := []string{"999"}
	w.Write(x)

	w.Flush() // 把在buffer緩存中的所有資料輸出

咦~~怎麼跟我預想的結果不太一樣?!

炸裂過後
炸裂過後

怎麼多了一堆莫名其妙的空格?

用EXCEL開,會看不清發生了什麼事情,
但以記事本開啟的話:

資料從原本的狀態
原始資料

變成這樣
炸裂過後

也就是說,我輸入的單行的資料是'999'\n',把原始資料1,2,3,4'\n'給蓋過去
將最前面四個字元覆蓋掉了,就變成999'\n'3,4'\n' ...

所以用Excel打開才會被解析成上方那樣的炸裂圖。

附加 Append CSV

打開檔案的時候以 O_APPEND 模式開啟,
就能不影響舊資料,將欲寫入的資料Append在最後了。

	file, err := os.OpenFile(FilePath, os.O_APPEND, 0777)

上一篇
# Day33 無內文 待補
下一篇
# Day35 Golang - Google Sheet 試算表應用 (Spreadsheet)
系列文
Go繁不及備載35

尚未有邦友留言

立即登入留言