【Java】CSVの読み書きを実施する方法(標準APIとライブラリ)

Java

はじめに

Java の実務では、CSVファイルを扱う場面が非常に多くあります。私自身も、業務システムの現場で「CSVを読み込んでDBに登録する」「処理結果をCSVで出力する」等、開発を実施した経験があります。
csvは一見シンプルですが、以下のようなはまりやすい部分も存在します。

  • 文字コード
  • カンマ区切りの扱い
  • 改行や空行
  • ヘッダー行の有無
  • ダブルクォートの扱い

今回は、Javaでcsvの取り扱いについてログとして記載していきたいと思います。

他にも、体系的にJavaを学びたい方には以下の教材がおすすめです:

👉スッキリわかるJava入門 
👉スッキリわかるJava入門 実践編

 

CSVとは

CSV(Comma-Separated Values)とは、カンマ(,)で項目を区切ったテキスト形式のデータです。

 

地方区分,都道府県番号,団体コード,都道府県名,よみ,県庁所在地,よみ
北海道地方,01,010006,北海道,ほっかいどう,札幌市,さっぽろし
東北地方,02,020001,青森県,あおもりけん,青森市,あおもりし
東北地方,03,030007,岩手県,いわてけん,盛岡市,もりおかし
東北地方,04,040002,宮城県,みやぎけん,仙台市,せんだいし
東北地方,05,050008,秋田県,あきたけん,秋田市,あきたし
東北地方,06,060003,山形県,やまがたけん,山形市,やまがたし

 

CSVを読み込む(標準API)

まずは、Java標準APIだけを使ったCSV読み込みから確認していきます。

 

  • BufferedReaderでファイルを読み込む
  • Charsetで文字コードを指定する
  • readLine() を使用して1行ずつ処理
  • split(",") でカンマ区切りに分解
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.Charset;

public class Sample {
    
        public static void main(String[] args) {
        String filePath = "todouhuken.csv";

        try (BufferedReader br = new BufferedReader(new FileReader(filePath, Charset.forName("UTF-8")))) {
            String line;

            // 1行ずつ読み込む
            while ((line = br.readLine()) != null) {
                String[] values = line.split(",");
                System.out.println(
                    "地方区分:" + values[0] +
                    ",都道府県名:" + values[3] +
                    ", 県庁所在地:" + values[5]
                );
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

ヘッダー行をスキップする方法

CSVの1行目がヘッダーであることがほとんどのため、1行目をスキップしてあげます。

boolean isFirstLine = true;

while ((line = br.readLine()) != null) {
    if (isFirstLine) {
        isFirstLine = false;
        continue; // ヘッダーをスキップ
    }

    String[] values = line.split(",");
    // データ処理
}

 

空行チェック

想定外のデータは必ずチェックし、ログを吐き出した上で無視する等の処理を実装しましょう。

if (line.trim().isEmpty()) {
    continue;
}

 

カンマを含むデータ

項目内にカンマを含むデータは、「split(“,”)」 では正しく分割できません。後述で説明するようなcsvのライブラリを使用しましょう。

 

CSVを書き込む(標準API)

次は、CSVファイルへの書き込みです。FileWriter でcsv形式でテキストを出力することで、csvファイルを作成することができます。

import java.io.FileWriter;
import java.io.IOException;

public class Sample2 {
        public static void main(String[] args) {
        String filePath = "output.csv";

        try (FileWriter writer = new FileWriter(filePath)) {
            writer.write("地方区分,都道府県名,県庁所在地\n");
            writer.write("北海道地方,北海道,札幌市\n");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

CSVライブラリ(Apache Commons CSV)

Java標準の String.split(",") は手軽ですが、実務CSVでは破綻しやすいです。理由としては以下が考えられます。

  • 項目に,を含む場合列ずれが発生してしまう
  • ダブルクォート(”)の扱いが、値の扱いとなってしまう

そのため、実務ではライブラリを使用するのが一般的です。

 

Apache Commons CSV

Mavenに依存関係を追加

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-csv</artifactId>
    <version>1.10.0</version>
</dependency>

 

CSV読み込み

ライブラリを使用して、csvを読み込む例を記載します。

  • 項目に、カンマ入り値も正しく扱える
  • 「setHeader」で1行目をヘッダとして扱うことができる
  • 「setSkipHeaderRecord」でヘッダを値として扱わないことができる
  • 「setTrim」で前後の空白を排除し、きれいな値として扱うことができる

import java.io.IOException;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;

public class Sample3 {
        public static void main(String[] args) throws IOException {
        Path path = Path.of("todouhuken.csv");

        try (Reader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8);
             CSVParser parser = CSVFormat.DEFAULT
                     .builder()
                     .setHeader()              // 1行目をヘッダーとして扱う
                     .setSkipHeaderRecord(true) // ヘッダー行自体はレコードとして扱わない
                     .setTrim(true)             // 前後空白を除去
                     .build()
                     .parse(reader)) {

            for (CSVRecord record : parser) {
                String ken = record.get("都道府県名");
                String shi = record.get("県庁所在地");

                System.out.printf("都道府県名=%s, 県庁所在地=%s", ken, shi);
            }
        }
    }
}

 

CSV書き込み

ライブラリを使用して、csvを書き込む例を記載します。

package com.example;

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;

import java.io.IOException;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;


public class Sample4 {
        public static void main(String[] args) throws IOException {
        Path out = Path.of("output.csv");

        try (Writer writer = Files.newBufferedWriter(out, StandardCharsets.UTF_8);
             CSVPrinter printer = new CSVPrinter(writer, CSVFormat.DEFAULT
                     .builder()
                     .setHeader("都道府県名", "県庁所在地")
                     .build())) {

            printer.printRecord("北海道", "札幌市");
        }
    }
}

 

まとめ

記事を参考に、CSVファイルを扱う際は注意が必要な点を意識して開発をしていきましょう。

  • 文字コード
  • カンマ区切りの扱い
  • 改行や空行
  • ヘッダー行の有無
  • ダブルクォートの扱い

 

ドキュメント

【公式ドキュメント】
Java SE Specifications (oracle.com)

 

最後に

Javaの環境構築は、この記事を参照してみてください。
【開発環境構築】VS CodeでJavaを使用するための環境構築を実施する – SEもりのLog (selifemorizo.com)

以上、ログになります。
これからも継続していきましょう!!

Javaサーバーサイド関連
シェアする
おすすめIT本
良いコード/悪いコードで学ぶ設計入門

「ITエンジニア本大賞2023」技術書部門で大賞を受賞した本です。
・コードの可読性
・普段意識したほうが良いこと
・リファクタリング考え方
等、普段のコードを設計する際に意識することが書かれています。
コードのあるべき姿に迷ったら一度読んでみると良い本です。

仕組みと使い方がわかる Docker&Kubernetesのきほんのきほん

Dockerって何?となったときに私が最初に読んだ本です。
Dockerがどんな仕組みで動いているのか、コマンドでは何を命令しているのかを理解できるように、イラストを多用して説明しています。

1冊ですべて身につくJavaScript入門講座

「ITエンジニア本大賞2024」技術書部門で大賞を受賞した本です。
私が次に読もうと思っている本なのでおすすめとして挙げておきたいと思います。

コメント

タイトルとURLをコピーしました