LoginSignup
6
7

More than 3 years have passed since last update.

こんにちは、エンジニアのミスダです。今回は、csvインポートでBOM付きのUTF-8の書き込み、読み込みに挑戦したことを記載します!

背景

業務系のシステムを開発していると一括で「データを作成したい!」って要望を受けます。。。
そんな時、私は、csvでのインポートを最初に考えます。APIを作成すると相手にも開発コストがかかりますしね。

ここで結構問題になるのは、csvの編集方法です。
Microsoft Excelを利用してないですか?やはり、編集しやすいですよね!

問題

Microsoft Excelの利用を考えて際に、Shift-JISでCSVを作成すれば編集できます。もし、DBがUTF-8だと、サーバー側で文字コードのコンバートが必要になります。こうなると、文字コードとの戦いです。正直、勝てる気がしません。

そんな時、BOM(byte order mark)付きのUTF-8であれば、Microsoft Excelで文字化けしないで開けるようです!

BOM付きでUTF-8ファイルの生成

今回は、JAVAでファイルの生成します。UTF-8の場合は、ファイルの先頭が【0xEF 0xBB 0xBF】になります。

import java.io.*;
import java.util.Arrays;
import java.util.List;

public class Main {

    /**
     * BOM付きのCSVファイルを作成(文字コードはUTF-8)
     *
     * @param 
     * @return 
     */
    public static void main(String[] args) {
        File file = new File("ファイルのパス");
        List header = Arrays.asList("りんご","みかん","バナナ","イチゴ","メロン","ぶどう");
        try(FileOutputStream fos = new FileOutputStream(file);
            OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
            PrintWriter writer = new PrintWriter(osw)){
            //BOM付与
            fos.write(0xef);
            fos.write(0xbb);
            fos.write(0xbf);

            header.forEach(c -> {
                writer.print(c);
                writer.print(",");
            });
        } catch (IOException e) {
            System.out.println("ファイルの生成に失敗。");
        }
    }

}

ファイルのインポート

生成したファイルが確実にBOM付きのUTF-8であればいいですが、そうでない場合もあります。判定を入れて読み込みします。

import java.io.*;
import java.nio.charset.StandardCharsets;
import org.apache.commons.codec.binary.Hex;


public class Main {

    /**
     * BOM付きのCSVファイルを読み込み(文字コードはUTF-8)
     *
     * @param
     * @return
     */
    public static void main(String[] args) {
        File file = new File("ファイルのパス");

        try (FileInputStream fs = new FileInputStream(file);
             InputStreamReader isr = new InputStreamReader(fs, StandardCharsets.UTF_8);
             LineNumberReader lnr = new LineNumberReader(isr)) {
            //1行目
            String row = lnr.readLine();
            if (row != null && !row.isEmpty()) {
                //先頭文字を取得
                String bom = row.substring(0, 1);
                //先頭文字をバイトを文字に変換する(Apache Commons CodecのHexクラスを利用)
                String bomByte = new String(Hex.encodeHex(bom.getBytes()));
                if ("efbbbf".equals(bomByte)) {
                    //BOMを排除
                    row = row.substring(1);
                }
                System.out.println(row);
            }
            //2行目から情報を分割する
        } catch (Exception e) {
            System.out.println("ファイルの読み込みに失敗。");
        }
    }
}

まとめ

MacOS、WindowsOS共に、Microsoft Excelで開いて文字化けもしてないし、編集もできた!あとは、テキストファイルを利用して編集してくれてる方かなと思います。そこは、サポートしていくしかないかな。

6
7
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
6
7