工作上半個月後需要處理csv檔,於是今天就在找處理csv的API,Apache commons裡面是不是有類似的API,http://commons.apache.org/csv/,前三個好像更新時間都蠻舊的,最後一個Super CSV最新,對於喜新厭舊的我來說,當然只想學新的,所以就選擇它來學習,SuperCVS個人覺得比POI容易許多,而且主要的CSVBeadReader可以把CSV直接轉成物件,透過反射特性與POJO結合,很快就可以把資料讀出來,另外CellProcessor可以限制或是轉換讀入的欄位資訊,例如不允許空白,或是日期轉換,以下是我參考官網寫的code。
官網:http://supercsv.sourceforge.net/index.html
原CSV檔
No Fx_ID Description Range Value Unit
FX-03 FX1T43K1088B-03 DI 5 s
FX-03 FX1T43K1093B-03 DI 60 s
FX-03 FX1T43K1098B-03 DI 5 s
FX-02 FX1T43K1098-02 PO 5 s
FX-02 FX1T43K1093-02 PO 5 s
FX-02 FX1T43K1088-02 PO 5 s
ProcessCSV
package read;
import java.io.FileReader;
import java.io.IOException;
import org.supercsv.cellprocessor.ConvertNullTo;
import org.supercsv.cellprocessor.constraint.NotNull;
import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.io.CsvBeanReader;
import org.supercsv.io.ICsvBeanReader;
import org.supercsv.prefs.CsvPreference;
import profile.FXDB;
public class ProcessCSV {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
ICsvBeanReader beanReader = null; //ICsvBeanReader是最上層介面,功能是csv檔讀成java bean
beanReader = new CsvBeanReader(new FileReader("D:\\FXDBChanges.csv"), CsvPreference.STANDARD_PREFERENCE);
//此行就是把CSV讀入beanReader,另外CsvBeanReader實做ICsvBeanReader,CsvPreference.STANDARD_PREFERENCE適用大多情況,另外其他參數值可參考API
final String[] header = beanReader.getHeader(true); //設定header
for(int i=0;i<header.length;i++)
System.out.print(header[i]+"\t");
System.out.println();
final CellProcessor[] processors=getProcessors(); //要處理beanReader物件前
FXDB fd; //必須定義CellProcessor,各項欄位的檢查規則
while( (fd= beanReader.read(FXDB.class, header, processors))!= null){ //透過反射機制把beadReader與FXDB物件連結,節省再new一個FXDB的物件,寫法很簡潔,比POI還簡單(定義HSSFROW/HSSFCELL.....)。
System.out.println(fd.getNo()+"\t"+fd.getFx_ID()+"\t"+fd.getDescription()+"\t"+fd.getValue()+
"\t"+fd.getRange()+"\t"+fd.getUnit());
}
System.out.println(beanReader.getRowNumber()); //1037列
beanReader.close(); //記得關閉,雖然該例別有實做autocloseable介面
}
private static CellProcessor[] getProcessors() { //CellProcessor是用來check各欄位的是否空白或是需要轉換
final CellProcessor[] processors = new CellProcessor[] {
new NotNull(), //第一欄, NotNull表不允許空白
new NotNull(), //下一欄以逗點隔開。
new NotNull(), //
new ConvertNullTo("NA"), //可以把Null轉換成其他字串
new NotNull(), //
new NotNull(), //
};
//更詳細地constraints分類可參考http://supercsv.sourceforge.net/cell_processors.html
return processors;
}
}
Output:
No Fx_ID Description Range Value Unit
FX-03 FX1T43K1088B-03 DI 5 NA s
FX-03 FX1T43K1093B-03 DI 60 NA s
FX-03 FX1T43K1098B-03 DI 5 NA s
FX-02 FX1T43K1098-02 PO 5 NA s
FX-02 FX1T43K1093-02 PO 5 NA s
FX-02 FX1T43K1088-02 PO 5 NA s