作爲新一代碼農,當下最最需要的就是把前輩們的已有成果變成自己掌握的知識。引用現成組件是一個敏捷開發要求中比較常用到的方法。昨天就被要求到用jxl的jar包來完成對Excel和數據庫兩者之間相互地讀寫的功能。
我寫了一個java項目來測試這塊功能。
首先是“讀”這一塊,從現有的Excel表格讀取數據到數據庫裏面,代碼貼上:
public class ReadXLS {
private static Log mLog = LogFactory.getLog(ReadXLS.class);
public static void readProductsFromXLS(Sheet sheet) throws ClassNotFoundException, SQLException {
Connection conn = JdbcUtil.getConn();
java.sql.PreparedStatement stmt = null;
stmt = conn.prepareStatement("insert into products values" +
"(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
//從i = 1 開始是因爲Excel表格第一行一般都是列名,所以數據時在第二行開始的。
for (int i = 1; i < sheet.getRows(); i++) {
for (int j = 0; j < 17; j++) {
Cell cell = sheet.getCell(j, i);
//這些判斷是很硬性的,暫時也沒有想到適應性更強的方法來對此進行判斷
if( j == 3 || j == 9 || j == 10 || j == 12 || j == 13){
stmt.setInt(j + 1, Integer.parseInt(cell.getContents()));
}else if(j == 7 || j == 8){
mLog.info("J ==" + j +"單元格內容爲:" + cell.getContents());
stmt.setFloat(j + 1, Float.parseFloat(cell.getContents()));
}else if(j == 11){
mLog.info("J ==" + j +"單元格內容爲:" + cell.getContents());
stmt.setTimestamp(j + 1, new Timestamp((
DateUtil.parse(DateUtil.FORMAT6, cell.getContents())).getTime()));
}else{
stmt.setString(j + 1, cell.getContents());
}
}
//考慮到性能問題,必須使用批處理
stmt.addBatch();
}
mLog.info("批處理執行");
stmt.executeBatch();
JdbcUtil.close(null, stmt, conn);
}
}
在“寫”這一塊,比較需要技巧,主要是對數組的操作。
public class CreateXLS {
/**
* *
* 步驟:1、通過Workbook提供的靜態方法createWorkbook(File file)來打開一個文件,並
* 得到一個WritableWorkbook的實例book,
* 2、通過實例book的createSheet(String name, int pageIndex)來創建紙張,
* 3、創建一個jxl.write.Label實例,並指定lable的行、列和值。
* 4、把label的實例添加到紙張sheet上。
* 5、book.write();寫入創建的實例和屬性;
* 6、關閉流book.close();
*/
public static void buildXls(WritableSheet sheet){
ProductDao prodDao = new ProductDaoImpl();
try {
//通過dao裏面的實現類來操作,所以在實現類裏,應該返回一個ArrayList,並且是二維的數組列表
ArrayList prods =(ArrayList) prodDao.load();
Label label = null;
for(int i= 0; i<prods.size();i++){
ArrayList inner = (ArrayList) prods.get(i);
for(int j=0; j < inner.size();j++){
label = new Label(j,i,inner.get(j).toString());
sheet.addCell(label);
}
}
} catch (RowsExceededException e) {
e.printStackTrace();
} catch (WriteException e) {
e.printStackTrace();
}
}
}
值得注意的是,jxl在對於使用Workbook操作讀和寫時,創建的對象是不一樣的,寫的是用一個可寫的WritableWorkbook,這種考慮,個人認爲應該是出於對性能的苛刻要求,在寫的book(工作簿)對象進行一系列操作完以後要進行“寫”的操作,就是book.wirte()。而對讀寫相同的操作都是需要對Cell來進行操作,即對每一個單元格操作,所以一般都會用到遍歷的方法。
附上一整個demo。