0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

CSVファイルの各フィールドの最初と最後に"を付けたい

Posted at

はじめに

以下のようなCSVファイルを作成したいと思った際に、はじめうまく作成できなかったので備忘録として作成方法を残しておこうと思います。

fruit.csv
"name","color","japanese"
"apple","red","りんご"
"grape","purple","ぶどう"
"orange","orange","オレンジ"

簡単に思いつく方法

作成したいCSVのコンテンツを用意し、encoding/csvパッケージを使用してCSVファイルを作成してみます。

package main

import (
	"encoding/csv"
	"os"
)

func main() {
	file, err := os.Create("./fruit.csv")
	if err != nil {
		panic(err)
	}
	defer file.Close()

	header := []string{"\"name\"", "\"color\"", "\"japanese\""}
	records := [][]string{
		{"\"apple\"", "\"red\"", "\"りんご\""},
		{"\"banana\"", "\"yellow\"", "\"バナナ\""},
		{"\"orange\"", "\"orange\"", "\"オレンジ\""},
	}

	csvWriter := csv.NewWriter(file)
	csvWriter.Write(header)
	csvWriter.WriteAll(records)
}

上記を実行すると以下のようになります。

fruit.csv
"""name""","""color""","""japanese"""
"""apple""","""red""","""りんご"""
"""banana""","""yellow""","""バナナ"""
"""grape""","""purple""","""ぶどう"""
"""orange""","""orange""","""オレンジ"""

ダブルクオートが各項目で3つになってしまいます。
これはencoding/csvWrite()関数で"があるとエスケープ処理が行われ、"が追加されるためです。
具体的には、

  1. エスケープが必要な文字を含むフィールドと判定される→フィールドの最初と最後に"を追加(""apple"")
  2. "をエスケープする必要があるので"の前に"を追加("""apple""")
    という処理が行われています。

つまりencoding/csvパッケージは"があると前後にダブルクオートを追加し、"の前にも"を追加する仕様になっています。

encoding/csvに渡す値 CSVファイルに出力される値
apple apple
app"le "app""le"
"apple" """apple"""

解決方法

encoding/csvパッケージを使うと難しいということがわかりました。
以下のように[]byteを作成しencoding/csvを使用しないでCSVを作成します。

main.go
package main

import (
	"fmt"
	"os"
	"strings"
)

func createByteSlice(s []string) []byte {
	str := strings.Join(s, ",")
	return []byte(fmt.Sprintf("%s\n", str))
}

func main() {
	file, err := os.Create("./fruit.csv")
	if err != nil {
		panic(err)
	}
	defer file.Close()

	header := []string{"\"name\"", "\"color\"", "\"japanese\""}
	records := [][]string{
		{"\"apple\"", "\"red\"", "\"りんご\""},
		{"\"grape\"", "\"purple\"", "\"ぶどう\""},
		{"\"orange\"", "\"orange\"", "\"オレンジ\""},
	}

	file.Write(createByteSlice(header))
	for _, record := range records {
		file.Write(createByteSlice(record))
	}
}

これを実行すると以下のCSVファイルを作成することができました。

fruit.csv
"name","color","japanese"
"apple","red","りんご"
"grape","purple","ぶどう"
"orange","orange","オレンジ"

おわりに

今回はCSVのフィールドに"を使用したい場合にGoを使ってどのように作成するかについて解説しました。
ダブルクオートをエスケープするというのはRFC4180で定義されている事項になります。
encoding/csvパッケージを用いることでよしなに処理してくれるので、通常はencoding/csvパッケージを使用するといいと思います!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?