Featured image of post JavaのCSVがエクセルで文字化けする原因と解決方法【BOM】

JavaのCSVがエクセルで文字化けする原因と解決方法【BOM】

JavaでUTF-8のCSVを書き出してもエクセルで開くと日本語が文字化けする原因はBOMが無いから。FileOutputStreamの先頭にBOMを書き込むだけで解決します。サンプルコードと確認結果つき♪

693文字

CSVの日本語がエクセルで文字化けする!

日本語が見れない

JavaBufferedWriterクラス等を用いてCSVファイルを生成する際、日本語が混じっているとソースコード上でUTF-8の指定をしていたとしてもエクセルで開くと文字化けしてしまうことがあります。

Csv.java
......
try {
	PrintWriter p =
		new PrintWriter(
			new BufferedWriter(
				new OutputStreamWriter(new FileOutputStream("export.csv"), "UTF-8")));
	// 1行目
	p.print("test");
	p.print(",");
	p.print("テスト");
	p.println();
	// 2行目
	p.print("サンプル");
	p.print(",");
	p.print("sample");
	// ファイルに書き出し閉じる
	p.close();
......

ちなみにMacのプレビューなどでは正常に表示されます。

原因はBOMが無いから

結論から言うと、原因としてはCSVファイルにBOMの指定が無いからです!

BOMとは、Byte Order Markの略となっていて、Microsoft ExcelはこのBOMがあるファイルのみUTF-8として解釈し、それ以外はデフォルトでSJISとして読み取ってしまうため、文字化けしてしまうようです。

それでは原因が分かったところで実際にソースコードに手を加えて解決していきましょう!

手順

FileOutputStreamにBOMを付与

対応方法はとても簡単で、以下のようにFileOutputStreamを一旦変数に代入し、行を記入する前にBOMの指定をするだけでOKです♪

Csv.java
......
try {
	FileOutputStream fos = new FileOutputStream("export.csv"); // 変数に代入
	PrintWriter p = new PrintWriter(
		new BufferedWriter(
			new OutputStreamWriter(fos, "UTF-8")));

	// BOM付与
	fos.write(0xef);
	fos.write(0xbb);
	fos.write(0xbf);
	// 1行目
......

確認

それでは出力したCSVファイルをエクセルで開いてみましょう!

無事に文字化けしなくなりましたね♪

終わりに

以上のように業務システムを作る際にはCSV出力機能を実装する事は多いと思いますが、知っていないと意外とハマるポイントです。

CSVファイルの文字化けにお悩みの方は是非試してみてください♪