Help us understand the problem. What is going on with this article?

[車輪の再発明]BeanをCSV形式で出力する

More than 5 years have passed since last update.

BeanをCSV形式にして出力するクラス。
s2csvとか使えないなどのどうしようもないときくらいしか使い道が無いかも。

BeanCSVWriter.java
package tools;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.lang.reflect.Field;
import java.nio.charset.Charset;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Pattern;

/**
 * Bean→CSV出力クラス
 *
 * @param <T> Bean
 */
public class BeanCSVWriter<T> implements AutoCloseable {

    private static final String EMPTY = "";
    private static final String QUOTATION = "\"";
    private static final String SEPARATOR = ",";
    private static final String LINE_SEPARATOR = "\r\n";

    private static final Pattern QUOTATION_PATTERN = Pattern.compile(QUOTATION);
    private static final Pattern SEPARATOR_PATTERN = Pattern.compile(SEPARATOR);

    private static final DateFormat DATE_FORMATER = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");

    private final BufferedWriter bw;

    /**
     * コンストラクタ
     * @param os 出力ストリーム
     * @param charset 文字コード
     */
    public BeanCSVWriter(OutputStream os, String charset) {
        OutputStreamWriter osw = new OutputStreamWriter(os, Charset.forName(charset));
        bw = new BufferedWriter(osw);
    }

    /**
     * 出力ストリームへ書き込む
     * @param bean Bean
     */
    public void write(T bean) {
        try {
            StringBuilder line = new StringBuilder();
            Field[] fields = bean.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                Object obj = field.get(bean);
                line.append(escape(obj)).append(SEPARATOR);
            }
            line.deleteCharAt(line.length() - 1);
            line.append(LINE_SEPARATOR);
            bw.write(line.toString());
        } catch (IllegalArgumentException | IllegalAccessException | IOException e) {
            throw new IORuntimeException(e);
        }
    }

    /**
     * エスケープ処理
     * @param obj 値
     * @return 文字列
     */
    private String escape(Object obj) {
        if (obj == null) {
            return EMPTY;
        }
        String str = null;
        if (obj instanceof Date) {
            str = DATE_FORMATER.format(obj);
        } else {
            str = obj.toString();
        }
        if (QUOTATION_PATTERN.matcher(str).find()) {
            str = str.replaceAll(QUOTATION, QUOTATION + QUOTATION);
        }
        if (SEPARATOR_PATTERN.matcher(str).find()) {
            str = QUOTATION + str + QUOTATION;
        }
        return str;
    }

    /**
     * クローズ
     */
    public void close() {
        try {
            bw.close();
        } catch (IOException e) {
            throw new IORuntimeException(e);
        }
    }
}
IORuntimeException.java
package tools;

/**
 * IOExceptionが発生時にThrowされる実行時例外
 */
public class IORuntimeException extends RuntimeException {

    /**
     * コンストラクタ
     * @param t 例外
     */
    public IORuntimeException(Throwable t) {
        super(t);
    }
}

使い方。

Main.java
package tools;

import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class Main {

    public static void main(String[] args) {
        List<CSVBean> beans = new ArrayList<CSVBean>();
        beans.add(new CSVBean(1, "山田", new Date()));
        beans.add(new CSVBean(2, "田中", new Date()));
        beans.add(new CSVBean(3, "中山田", new Date()));
        beans.add(new CSVBean(4, "中\"山田", new Date()));
        beans.add(new CSVBean(5, "中山,田", new Date()));
        beans.add(new CSVBean(6, "中\"山,田", new Date()));

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try (BeanCSVWriter<CSVBean> writer = new BeanCSVWriter<CSVBean>(baos, "UTF-8")) {
            for (CSVBean bean : beans) {
                writer.write(bean);
            }
        }

        System.out.println(baos.toString());
    }

    public static class CSVBean {
        public Integer id;
        public String name;
        public Date date;

        public CSVBean(Integer id, String name, Date date) {
            this.id = id;
            this.name = name;
            this.date = date;
        }
    }
}
hina0118
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away