Super CSV是一個用于處理CSV文件的Java開源項目。它完全圍繞面向對象的思想進行設計,因此可以利用你的面向對象代碼來使得處理CSV文件變得更加簡易。它支持輸入/輸出類型轉換、數據完整性校驗,支持從任何地方以任何編碼讀寫數據,只要提供相應的Reader與Writer對象。可配置分割符,空格符號和行結束符等。
下面來看一下官方文檔中的代碼示例。
1. 根據頭來讀取CSV文件
把文件中的每行記錄讀取出來轉化為java對象,假設你有一個UserBean類,代碼如下:
public class UserBean {
String username, password, street, town;
int zip;
public String getPassword() { return password; }
public String getStreet() { return street; }
public String getTown() { return town; }
public String getUsername() { return username; }
public int getZip() { return zip; }
public void setPassword(String password) { this.password = password; }
public void setStreet(String street) { this.street = street; }
public void setTown(String town) { this.town = town; }
public void setUsername(String username) { this.username = username; }
public void setZip(int zip) { this.zip = zip; }
}
并且有一個CSV文件,包含一個文件頭,假設文件內容如下:
username, password, date, zip, town
Klaus, qwexyKiks, 17/1/2007, 1111, New York
Oufu, bobilop, 10/10/2007, 4555, New York
class ReadingObjects {
public static void main(String[] args) throws Exception{
ICsvBeanReader inFile = new CsvBeanReader(new FileReader("foo.csv"), CsvPreference.EXCEL_PREFERENCE);
try {
final String[] header = inFile.getCSVHeader(true);
UserBean user;
while( (user = inFile.read(UserBean.class, header, processors)) != null) {
System.out.println(user.getZip());
}
} finally {
inFile.close();
}
}
}
我們還剩下processors沒有定義,通過名字我們可以看出是解析器,用來處理每列的數據,當然你也可以傳入null,表示該列不做特殊處理,每個解析器可以被另外一個包含在內部,new Unique(new StrMinMax(5,20)),這個代碼該列的值為唯一的,并且長度為8到20,具體處理細節我們先不講,來看一下我們所需要的processors是如何定義的:
final CellProcessor[] processors = new CellProcessor[] {
new Unique(new StrMinMax(5, 20)),
new StrMinMax(8, 35),
new ParseDate("dd/MM/yyyy"),
new Optional(new ParseInt()),
null
};
上面的代碼的具體意思為:
第一列是一個字符串,并且值是唯一的,長度為5到20
第二列是一個字符串,長度是8到35
第三列為一個日期類型,格式為天/月/年(day/month/year)
第四列是一個整型數字,但只有這列有值的時候ParseInt處理器才會去處理這個值(其實就是該列可以為空)
第五列為一個字符串(默認),不使用處理器
如果你的CSV文件沒有頭,你也可以定義個數組來替代:
final String[] header = new String[] { "username", "password", "date", "zip", "town"};
如果你想忽略某一列,和定義處理器類似,直接在頭數組中使用null。
全部代碼如下:
import Java.io.FileReader;
import Java.io.IOException;
import org.supercsv.cellprocessor.Optional;
import org.supercsv.cellprocessor.ParseDate;
import org.supercsv.cellprocessor.ParseInt;
import org.supercsv.cellprocessor.constraint.StrMinMax;
import org.supercsv.cellprocessor.constraint.Unique;
import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.io.CsvBeanReader;
import org.supercsv.io.ICsvBeanReader;
import org.supercsv.prefs.CsvPreference;
class ReadingObjects {
static final CellProcessor[] userProcessors = new CellProcessor[] {
new Unique(new StrMinMax(5, 20)),
new StrMinMax(8, 35),
new ParseDate("dd/MM/yyyy"),
new Optional(new ParseInt()),
null
};
public static void main(String[] args) throws Exception {
ICsvBeanReader inFile = new CsvBeanReader(new FileReader("foo.csv"), CsvPreference.EXCEL_PREFERENCE);
try {
final String[] header = inFile.getCSVHeader(true);
UserBean user;
while( (user = inFile.read(UserBean.class, header, userProcessors)) != null) {
System.out.println(user.getZip());
}
} finally {
inFile.close();
}
}
}
public class UserBean {
String username, password, town;
Date date;
int zip;
public Date getDate() {
return date;
}
public String getPassword() {
return password;
}
public String getTown() {
return town;
}
public String getUsername() {
return username;
}
public int getZip() {
return zip;
}
public void setDate(final Date date) {
this.date = date;
}
public void setPassword(final String password) {
this.password = password;
}
public void setTown(final String town) {
this.town = town;
}
public void setUsername(final String username) {
this.username = username;
}
public void setZip(final int zip) {
this.zip = zip;
}
}
如果你在讀取文件之前根本不知道文件的具體格式,你可以選擇CsvListReader.read()方法,把每行讀出出來的數據放在一個List里面。
讀取文件的代碼我們看到了,下面來看一下寫的操作,也很簡單。
import Java.util.HashMap;
import org.supercsv.io.*;
import org.supercsv.prefs.CsvPreference;
class WritingMaps {
main(String[] args) throws Exception {
ICsvMapWriter writer = new CsvMapWriter(new FileWriter(...), CsvPreference.EXCEL_PREFERENCE);
try {
final String[] header = new String[] { "name", "city", "zip" };
// set up some data to write
final HashMap<String, ? super Object> data1 = new HashMap<String, Object>();
data1.put(header[0], "Karl");
data1.put(header[1], "Tent city");
data1.put(header[2], 5565);
final HashMap<String, ? super Object> data2 = new HashMap<String, Object>();
data2.put(header[0], "Banjo");
data2.put(header[1], "River side");
data2.put(header[2], 5551);
// the actual writing
writer.writeHeader(header);
writer.write(data1, header);
writer.write(data2, header);
} finally {
writer.close();
}
}
}