5分でできる!簡単なcsvデータの加工(read/write)法。(Java編)

仕事やプライベートで?受け取ったcsvのデータを、自分の思うようにちょっと加工したいときってありませんか?

項目の順番を入れ替えたり、文字列に加工したりして、自分の使いやすい形に整形したいというシーンは結構あると思います。

Script系の言語を使ったり、SedやAwkを使う!という人もいるでしょうね。私はjavaが使い慣れているので、今回はJavaを使ってみたいと思います。

いくつか便利なライブラリがあるようですが、私は、opencsvが使いやすいと思いました。

opencsvでは、csvファイルの読み込みの方法をいくつか指定することができます。

どの方法を利用して読み込みを行うかはMappingStrategyクラスを切り替えることで指定できます。

HeaderColumnNameTranslateMappingStrategy

HeaderColumnNameMappingStrategy

などはヘッダ項目をもつcsvファイルを扱うのに便利なクラスのようですね。私が今回利用したのはColumnPositionMappingStrategyクラスです。

csvファイルを簡単に加工するというのが目的ですので、読み込み/書き込みの記述が比較的シンプルな方法を選択しました。

準備作業

参照するjar(ライブラリ)

コンパイルに必要なライブラリは以下の通りです。OpenCVはもちろん必要ですが、「commons-beanutils」と「org.apache.commons」も必要なので、詳細は、ここのdependenciesを確認しましょう。

※2016/09/01に再検証した時点では、以下のjarが必要でした。

  • opencsv-3.8.jar
  • commons-beanutils-1.9.2.jar
  • commons-lang3-3.4.jar

読み込みに使うcsvファイル

実際に読み書きに使用するcsvファイルを適当なディレクトリに用意します。サンプルとして、「SampleIn.csv」というファイルをUTF-8の文字コードで作成しました。

key,name,pref,job
key1,name1,pref1,job1
key2,名前2,県2,お仕事2

上記のような内容のcsvで良いと思います。1行目がヘッダで、このヘッダ名をキーに下記の「String[]{“key”, “name”, “pref”, “job”}」で対応付けて読み取ります。

csvを扱うクラスの作成

まず、読み込み対象のcsvファイルの項目に対応する単純なJavaBeansクラスを定義します。項目さえ定義すれば、SetterとGetterはEclipseなどのIDEが自動で吐いてくれますよね。

コンストラクタで空白をセットしておいてあげると、空行とかを読み込んだときにエラーで落ちることを防いでくれます。

SampleCsvBeanクラス

package jp.koji.bean;
 
public class SampleCsvBean {
 
    String key;
    String name;
    String pref;
    String job;
 
    public SampleCsvBean() {
        this.key = "";
        this.name = "";
        this.pref = "";
        this.job = "";
    }
 
    public String getKey() {
        return key;
    }
 
    public void setKey(String key) {
        this.key = key;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getPref() {
        return pref;
    }
 
    public void setPref(String pref) {
        this.pref = pref;
    }
 
    public String getJob() {
        return job;
    }
 
    public void setJob(String job) {
        this.job = job;
    }
 
}

次に、作成したJavaBeansクラスを読み書きする、Mainクラスを作成します。

MainCSVUtil

package jp.koji.bean;
 
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.OutputStreamWriter;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.Writer;
import java.util.Iterator;
import java.util.List;
 
import com.opencsv.CSVReader;
import com.opencsv.CSVWriter;
import com.opencsv.bean.ColumnPositionMappingStrategy;
import com.opencsv.bean.CsvToBean;
 
public class MainCSVUtil {
     
    public static void main(String[] arg) throws Exception {
          
        writeSampleCSV("D:\\SampleOut.csv",readSampleCSV("D:\\SampleIn.csv"));
      
    }
 
     
    public static List readSampleCSV(String inputFilePath){
          
        Reader ioreader = null;
        List tmpNDCsvBean = null;
      
        try {
      
            ioreader = new InputStreamReader(new FileInputStream(inputFilePath),"UTF-8");
      
            ColumnPositionMappingStrategy mappingStrategy = new ColumnPositionMappingStrategy();
            mappingStrategy.setType(SampleCsvBean.class);
      
            String[] columns = new String[]{"key", "name", "pref", "job"};
            mappingStrategy.setColumnMapping(columns);
      
            CsvToBean csv = new CsvToBean();
            CSVReader reader = new CSVReader(ioreader, ',', '"');
            tmpNDCsvBean = csv.parse(mappingStrategy, reader);
      
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
      
            try{
                ioreader.close();
            }catch(Exception e){
                e.printStackTrace();
            }
        }
      
        return tmpNDCsvBean;
    }
     
    public static void writeSampleCSV (String outputFilePath, List listCSVBean){
          
        Writer iowriter = null;
        CSVWriter writer = null;
        try {
      
            iowriter = new OutputStreamWriter(new FileOutputStream(outputFilePath),"UTF-8");
            writer = new CSVWriter(iowriter, ',', CSVWriter.NO_QUOTE_CHARACTER);
      
            Iterator<samplecsvbean> ite = listCSVBean.iterator();
            while(ite.hasNext()){
      
                SampleCsvBean tt = ite.next();
      
                String[] entries = new String[]{tt.getKey(),
                                                tt.getName(),
                                                tt.getPref(),
                                                tt.getJob().replace(",", "、")
                                                };
      
                writer.writeNext(entries);
      
            }
            writer.close();
      
        }catch (Exception e) {
            e.printStackTrace();
        }finally{
      
            try{
                iowriter.close();
            }catch(Exception e){
                e.printStackTrace();
            }
      
        }
      
    }
     
}

一旦読み込むと、定義したJavaBeans型のリストとなるので、その後の加工は自由自在です。加工した結果を、csvに吐き出すコードは、上記の「writeSampleCSV」です。

一つ作っておくと、いろいろなcsvを加工するのも楽ですよ。