5年も前に CSVを生成する Javaプログラムコードを、csv4j を使って書いていた。
2011年 3月
http://oboe2uran.hatenablog.com/entry/2011/03/19/101643CSV書き込み(1) - Oboe吹きプログラマの黙示録
http://oboe2uran.hatenablog.com/entry/2011/03/22/210219CSV書き込み(2) - Oboe吹きプログラマの黙示録
http://oboe2uran.hatenablog.com/entry/2011/03/25/121714CSV書き込み(3) - Oboe吹きプログラマの黙示録
でも、1年前、これだと使い勝手が悪くて、 net.sf.csv4j.CSVWriter を使いたくなり、当時、環境としても Java7のままだったので、
次のインターフェースを用意して
public interface Csvoutable{ /** * net.sf.csv4j.CSVWriter#writeLine(String[]) に渡す String[] を生成する。. * @return String[] */ public String[] arrays(); }
このインターフェースで受け取った文字列配列をCSV出力する抽象クラスを用意して使った。
import java.io.OutputStream; import java.io.OutputStreamWriter; import java.util.Collection; import java.util.function.Supplier; import net.sf.csv4j.CSVWriter; /** * CSV作成抽象クラス. */ public abstract class CsvBinary{ /** * ヘッダ行の提供. * @return CSVヘッダとなるString配列 */ protected abstract String[] getHeaders(); /** * CSVコンテンツ行の提供. * @return CSVコンテンツとなる Csvoutable のコレクション */ protected abstract Collection<? extends Csvoutable> getElements(); /** * CSV生成. * @param bout 書込み先 OutputStream */ public void write(OutputStream out){ try{ OutputStreamWriter writer = new OutputStreamWriter(out, "MS932"); CSVWriter csvWriter = new CSVWriter(writer); csvWriter.writeLine(getHeaders()); for(Csvoutable c:getElements()){ String[] a = c.arrays(); String[] s = new String[a.length]; for(int i=0;i < s.length;i++){ s[i] = a[i]==null ? "" : a[i]; } csvWriter.writeLine(s); } writer.close(); }catch(Exception e){ throw new RuntimeException(e.getMessage(), e); } } }
使用例は、、
CsvBinary csvbinary = new CsvBinary(){ @Override protected String[] getHeaders(){ return new String[]{ "A", "B", "C" }; } @Override protected Collection<? extends Csvoutable> getElements(){ return getLineData(); } };
のように生成して、getElements で呼ぶgetLineDataは、、
rotected List<Csvoutable> getLineData(){ List<Csvoutable> csvlist = new ArrayList<Csvoutable>(); // DB読込み等ハンドラの中で以下を実行 csvlist.add(new Csvoutable(){ @Override public String[] arrays(){ return new String[]{ "11","12","テスト" }; } }); return csvlist; }
CSVのヘッダ行とデータ行の書込みを明示的で見通しが良いと、1年前は思っていた。
でも、長くて複雑な出力要求がきたら、どうなんだ!?
→ そういう要件自体が問題なんですけど。
Csvoutable に、@FunctionalInterface() を付けたところで
1行書き出し文が、ラムダに代わるくらい、、、
Collection
としても、、
たいして魅力的なコードにはならない。
→ つづきを、CSV書込み(2)で。。。