日期:2014-05-16  浏览次数:20607 次

Excel和Database双向读写

????? 作为新一代码农,当下最最需要的就是把前辈们的已有成果变成自己掌握的知识。引用现成组件是一个敏捷开发要求中比较常用到的方法。昨天就被要求到用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。