kurukuru-papaのブログ

主に、ソフトウェア開発に関連したメモを書き溜めたいと思います。

SuperCSV 読み込み時、カラム順序を動的に判断

SuperCSVには、読み込むファイルのカラム順序を適宜判断して、読み込む機能がありました。高機能ですね。

この機能を使うためには2つポイントが有りました。

  1. 読み込むファイルの1行目に、適切なカラム名称が記述されている必要があります。
  2. カラム名称と、Beanの項目、それからカラムの値を解析するCellProcessorとの対応付けを判断するロジックを記述します。

具体的には、次のようにして使うことができました。まず、読み込み処理です。ここでは、自分で作成したMeisaiCellProcessorsクラスを呼んでいるのがポイントです。

List<MeisaiBean> list = new ArrayList<MeisaiBean>();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
ICsvBeanReader reader = new CsvBeanReader(br, CsvPreference.EXCEL_PREFERENCE);
int count = 0;

try {
	// ヘッダー部を読み込む
	count++;
	String[] header = reader.getCSVHeader(true);
	// データ部を読み込む
	MeisaiBean bean = null;
	MeisaiCellProcessors processors = new MeisaiCellProcessors(header);
	while (true) {
		count++;
		bean = reader.read(MeisaiBean.class, processors.getHeader(),
				processors.getCellProcessors());
		if (bean == null) {
			break;
		}
		list.add(bean);
	}
} catch (Exception e) {
	throw new RuntimeException("ファイル読み込みに失敗しました。行番号=[" + count + "]", e);
} finally {
	reader.close();
}

MeisaiCellProcessorsクラスです。対象のBeanクラスには、XXXCellProcessorというプロパティ名(static)で、適切なCellProcessorが定義されている前提です。XXX部分は、カラム名称です。不要なカラムが存在する場合は、無視するようにしています。カラムが足りない場合には対応出来ていません。

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

public class MeisaiCellProcessors {
	private List<String> header;
	private List<CellProcessor> cellProcessors;

	public MeisaiCellProcessors(String[] inFileHeader) {
		header = new ArrayList<String>();
		cellProcessors = new ArrayList<CellProcessor>();

		for (String columnName : inFileHeader) {
			try {
				String methodName = null;
				CellProcessor cp = null;
				if (columnName.length() > 0) {
					Class<MeisaiBean> c = MeisaiBean.class;
					Field f = c.getField(columnName.substring(0, 1)
							.toLowerCase()
							+ columnName.substring(1) + "CellProcessor");
					cp = (CellProcessor) f.get(null);
					methodName = columnName;
				}
				header.add(methodName);
				cellProcessors.add(cp);
			} catch (NoSuchFieldException e) {
				// 無視するカラムにはnullを入れる
				header.add(null);
				cellProcessors.add(null);
			} catch (Exception e) {
				throw new RuntimeException("ヘッダーの解析に失敗しました。name=[" + columnName
						+ "]", e);
			}
		}
	}

	public String[] getHeader() {
		return header.toArray(new String[] {});
	}

	public CellProcessor[] getCellProcessors() {
		return cellProcessors.toArray(new CellProcessor[] {});
	}
}

すいません。もう眠くなってきましたので、ここで終りとします。

動作環境

  • OS : Windows 7
  • JDK : Version 1.6.0
  • SuperCSV : Version 1.52