JavaでCSVファイル出力をする

Java (Spring Boot や Android) において、
CSVファイル出力を行う際のサンプルコードをまとめます。

仕様

  • 文字コード: UTF-8 with BOM
  • 改行コード: CRLF (\r\n)
  • 区切り文字: , (カンマ)
  • フィールド内改行: 可

BOMの出力

BOMは、ファイルの先頭に \uFEFF を出力するだけです。
ヘッダー行とともに出力してしまっても良いかと思います。

File file = new File(filePath);
boolean fileExists = file.exists();
try (FileWriter writer = new FileWriter(file, true)) {
    if (!fileExists) {
        writer.write("\uFEFF");
    }

    // ...
}
catch (IOException e) {
    Log.d(TAG, e.getMessage());
}

レコードの出力

各フィールドをカンマで区切り、改行文字を追加し、先ほどのファイルに出力します。
これを、レコードの数だけ繰り返します。 ※escapeCsv関数は後述

// ...

writer.write(escapeCsv(data.id) + ","
    + escapeCsv(data.name) + ","
    + escapeCsv(data.address) + "\r\n"
);

// ...

フィールドのエスケープ処理

フィールド内に、カンマ・ダブルクォーテーション・改行のいずれかが含まれる場合、
以下の処理を行います。含まれない場合は、文字列をそのまま出力します。

  • フィールド内のダブルクォーテーションをエスケープ処理します
  • 改行文字をCRLFに統一します
  • フィールドをダブルクォーテーションで囲みます
public String escapeCsv(String input) {
    if (input.matches(".*(,|\"|\r|\n|\r\n).*")) {
        return "\"" + input.replaceAll("\"", "\"\"")
            .replaceAll("([^\r])\n|\r([^\n])", "$1\r\n$2") + "\"";
    }
    else {
        return input;
    }
}

※改行文字の置換により、改行の数が増えてしまう恐れがあります
※細かい部分は、仕様に合わせて調整ください