由于平时经常需要处理读取Excel,所以写了这样一个小模块来处理读取Excel...
关于写出Excel的功能,以后再写一个通用的。
更新:针对数字转字符串增加转换,对15位以下数据有效,超过15位的本身就已经错误了..读取的值和Excel是对应的。
例如:13909909909123123写到Excel就成了13909909909123100,读取的也是13909909909123100
一共有3个文件,分别为:
ColT.java 对单元格列的类型定义
ExcelObj.java 将Excel读取到简单类,该类必须继承
ExcelRead.java 读取Excel的类
源码:
Colt.java
package com.liuzh.excel; /** * 单元格可用类型 * @author Liuzh * */ public class ColT { /**不对列进行类型转换*/ public static final int NO = 0; /**字符串类型*/ public static final int cSTRING = 1; /**整型*/ public static final int cINT=2; /**单精度浮点*/ public static final int cFlOAT=3; /**双精度浮点*/ public static final int cDOUBLE=4; /**日期类型*/ public static final int cDATE=5; /**长整型*/ public static final int cLONG=6; /**代码值,使用该类型需要设置codeType*/ public static final int cCode=7; }
package com.liuzh.excel; import java.lang.reflect.Method; /** * 基础类,使用此功能的类需要继承该类 * @author Liuzh * */ public abstract class ExcelObj { private String errMsg; public String getErrMsg() { return errMsg; } public void setErrMsg(String errMsg) { this.errMsg = errMsg; } /** * 通过属性名设置属性值 * @param name * @param value */ @SuppressWarnings("unchecked") public void putValue(String name,Object value){ Class c = this.getClass(); Class v = value.getClass(); try{ Method m = c.getMethod("set"+name, new Class[]{v}); m.invoke(this, new Object[]{value}); }catch(Exception e){ e.printStackTrace(); } } /** * 返回属性名对应的值 * @param name * @return 属性名对应的值 */ @SuppressWarnings("unchecked") public Object outValue(String name){ Class c = this.getClass(); Object o =null; try{ Method m = c.getMethod("get"+name, new Class[]{}); o = m.invoke(this, new Object[]{}); }catch(Exception e){ e.printStackTrace(); } return o; } }
package com.liuzh.excel; import java.io.File; import java.io.FileInputStream; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.List; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; /** * 获取excel内容 * @author Liuzh * */ public class ExcelRead { /**列名*/ private String[] colnumName; /**列类型*/ private Integer[] colnumType; /**代码KV*/ private HashMap<String,Object> codeType; /**写入到的Object类型,该方法必须继承ExcelObj才可以使用*/ private ExcelObj DTO; public ExcelObj getDTO() { return DTO; } public void setDTO(ExcelObj dto) { DTO = dto; } public String[] getColnumName() { return colnumName; } public void setColnumName(String[] colnumName) { this.colnumName = colnumName; } public Integer[] getColnumType() { return colnumType; } public void setColnumType(Integer[] colnumType) { this.colnumType = colnumType; } public HashMap<String, Object> getCodeType() { return codeType; } public void setCodeType(HashMap<String, Object> codeType) { this.codeType = codeType; } /** * 获取excel到一个List<List<HashMap<String,Object>>>,从第一个sheet页的第一行开始读取 * 从外到内依次为:sheet页,行,单元格 * @param file 要读取的文件 * @return 返回一个List<List<HashMap<String,Object>>>对象 * @throws Exception */ public List<List<HashMap<String,Object>>> getExcel(File file) throws Exception { return getExcel(file,0,0); } /** * 获取excel到一个List<List<HashMap<String,Object>>> * 从外到内依次为:sheet页,行,单元格 * @param file 要读取的文件 * @param snum 读取那个sheet页,从0算起 * @param rnum 从那行开始读取,从0算起 * @return 返回一个List<List<HashMap<String,Object>>>对象 * @throws Exception */ @SuppressWarnings("deprecation") public List<List<HashMap<String, Object>>> getExcel(File file,int snum,int rnum) throws Exception { List<List<HashMap<String, Object>>> list = new ArrayList<List<HashMap<String, Object>>>(); Object localObject = null; // 传入路径 FileInputStream is = new FileInputStream(file); HSSFWorkbook wbs = new HSSFWorkbook(is); HSSFSheet childSheet = wbs.getSheetAt(snum); for (int j = rnum; j <= childSheet.getLastRowNum(); j++) { //读取行元素 List<HashMap<String, Object>> listrow = new ArrayList<HashMap<String, Object>>(); HSSFRow row = childSheet.getRow(j); if (null != row) { HashMap<String, Object> cellv = null; for (int k = 0; k < row.getLastCellNum(); k++) { //读取单元格 HSSFCell cell = row.getCell((short) k); cellv = new HashMap<String, Object>(); if(cell == null){ cellv.put(colnumName[k], null); listrow.add(cellv); continue; } else{ // 判断获取类型 switch (cell.getCellType()) { case HSSFCell.CELL_TYPE_NUMERIC: localObject = cell.getNumericCellValue(); break; case HSSFCell.CELL_TYPE_STRING: localObject = cell.getStringCellValue(); break; case HSSFCell.CELL_TYPE_BOOLEAN: localObject = new Boolean(cell.getBooleanCellValue()); break; case HSSFCell.CELL_TYPE_BLANK: localObject = ""; break; case HSSFCell.CELL_TYPE_FORMULA: int a = (cell.getCellFormula().indexOf("+") + 1) + (cell.getCellFormula().indexOf('/') + 1) + (cell.getCellFormula().indexOf('*') + 1) + (cell.getCellFormula().indexOf('-') + 1); if (a <= 0){ localObject = cell.getCellFormula(); } else if (a > 0){ localObject = cell.getNumericCellValue(); } break; case HSSFCell.CELL_TYPE_ERROR: localObject = new Byte(cell.getErrorCellValue()); break; default: System.out.println("未知类型"); break; } try { //限制类型的时候,做下面的类型强制转换 if(colnumType!=null){ localObject = getRightTypeValue(localObject, k); } } catch (Exception e) { cellv.put("ErrMsg", e.getMessage()); listrow.add(cellv); continue; } cellv.put(colnumName[k], localObject); } listrow.add(cellv); } list.add(listrow); } } return list; } /** * 获取excel到一个List<List<HashMap<String,Object>>> * @param filepath Excel文件路径 * @return 返回一个List<List<HashMap<String,Object>>>对象 * @throws Exception */ public List<List<HashMap<String, Object>>> getExcel(String filepath) throws Exception { File file = new File(filepath); return getExcel(file,0,0); } /** * 获取excel到一个List<List<HashMap<String,Object>>> * @param filepath Excel文件路径 * @param snum 读取那个sheet页,从0算起 * @param rnum 从那行开始读取,从0算起 * @return 返回一个List<List<HashMap<String,Object>>>对象 * @throws Exception */ public List<List<HashMap<String, Object>>> getExcel(String filepath,int snum,int rnum) throws Exception { File file = new File(filepath); return getExcel(file,snum,rnum); } /** * 读取到excel到List<Object>从第一个sheet页的第一行开始读取 * @param file 要读取的文件 * @return 返回一个List<Object>对象 * @throws Exception */ public List<Object> getExcelObj(File file) throws Exception{ return getExcelObj(file,0,0); } /** * 读取到excel到List<Object> * @param file 要读取的文件 * @param snum 读取那个sheet页,从0算起 * @param runm 从那行开始读取,从0算起 * @return 返回一个List<Object>对象 * @throws Exception */ @SuppressWarnings("unchecked") public List<Object> getExcelObj(File file,int snum,int runm) throws Exception{ List<Object> list = new ArrayList<Object>(); Class c = DTO.getClass(); ExcelObj dto = null; List<List<HashMap<String, Object>>> exceldata = getExcel(file,snum,runm); if(exceldata!=null){ for(List<HashMap<String, Object>> lista:exceldata){ dto = (ExcelObj)c.newInstance(); dto.putValue("ErrMsg",""); for(int iii=0;iii<lista.size();iii++){ HashMap<String, Object> hm = lista.get(iii); if(hm.get(colnumName[iii])!=null){ dto.putValue(colnumName[iii], hm.get(colnumName[iii])); } else{ dto.putValue("ErrMsg", dto.outValue("ErrMsg")+"第"+(iii+1)+"列存在为空的值;"); continue; } } list.add(dto); } } return list; } /** * 读取到excel到List<Object> * @param filepath Excel文件路径 * @return 返回一个List<Object>对象 * @throws Exception */ public List<Object> getExcelObj(String filepath) throws Exception{ File file = new File(filepath); return getExcelObj(file,0,0); } /** * 读取到excel到List<Object> * @param filepath Excel文件路径 * @param snum * @param runm * @return 返回一个List<Object>对象 * @throws Exception */ public List<Object> getExcelObj(String filepath,int snum,int runm) throws Exception{ File file = new File(filepath); return getExcelObj(file,snum,runm); } /** * 这里获取的值是输入正确,但是单元格属性设置错误导致类型错误,需要矫正的值 * @param localObject * @param k * @return 经过类型矫正的值 * @throws Exception */ @SuppressWarnings("unchecked") private Object getRightTypeValue(Object localObject, int k) throws Exception { switch(colnumType[k]){ case ColT.NO://不做任何转换 break; case ColT.cCode: //需要根据KV转换规则进行转换 Object colType = codeType.get(colnumName[k]); if(colType!=null){ HashMap<String,Object> colHm = (HashMap<String,Object>)colType; Object colObj = colHm.get(localObject.toString()); if(colObj==null){ throw new Exception("找不到对应的代码值!"); } else{ localObject = colObj; } } else{ Object obj = codeType.get(localObject.toString()); if(obj==null){ throw new Exception("找不到对应的代码值!"); } else{ localObject = obj; } } break; case ColT.cDATE: if (!(localObject instanceof Date)) { if(localObject instanceof String){ //按照格式yyyy-MM-dd转换 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); localObject = sdf.parse(localObject.toString()); } else if(localObject instanceof Double){ int day = ((Double)localObject).intValue(); Calendar c=Calendar.getInstance(); c.set(1900, 0, 1); c.add(Calendar.DAY_OF_YEAR, day); localObject = c.getTime(); } else{ throw new Exception("日期格式错误"); } } break; case ColT.cDOUBLE: if(!(localObject instanceof Double)){ if(localObject instanceof String){ localObject = Double.parseDouble(localObject.toString()); } } break; case ColT.cFlOAT: if(localObject instanceof Double){ localObject = ((Double)localObject).floatValue(); } break; case ColT.cINT: if(localObject instanceof Double){ localObject = ((Double)localObject).intValue(); } break; case ColT.cLONG: if(localObject instanceof Double){ localObject = ((Double)localObject).longValue(); } break; case ColT.cSTRING: if(localObject instanceof Double){ java.text.DecimalFormat formatter = new java.text.DecimalFormat( "######## "); localObject = formatter.format(localObject); } else{ localObject = localObject.toString(); } break; } return localObject; } }
TestObj.java
package com.test; import java.util.Date; import com.liuzh.excel.ExcelObj; public class TestObj extends ExcelObj{ private String name; private Integer age; private String sex; private Date birthday; private String address; private String email; private String phone; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } @Override public String toString() { return name+","+age+","+email+","+phone+","+address; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } }
package com.test; import java.io.File; import java.util.HashMap; import java.util.List; import com.liuzh.excel.ColT; import com.liuzh.excel.ExcelRead; /** * 测试类 * @author Liuzh * */ public class ExcelTest { public static void main(String[] args) throws Exception { String[] name = {"Name","Age","Sex","Birthday","Address","Email","Phone"}; Integer[] type={ColT.cSTRING,ColT.cINT,ColT.cCode,ColT.cDATE,ColT.cSTRING,ColT.cSTRING,ColT.cSTRING}; HashMap<String,Object> code = new HashMap<String, Object>(); HashMap<String,Object> codeList = new HashMap<String, Object>(); code.put("1", "男"); code.put("2", "女"); codeList.put("Sex", code); ExcelRead excel = new ExcelRead(); //存入文件列名,必填项 excel.setColnumName(name); //文件列名对应类型,可选,不写可能会出现异常 excel.setColnumType(type); //使用code类型时,必须设置codetype excel.setCodeType(codeList); //使用getExcelObj方法必须设置 excel.setDTO(new TestObj()); File file=new File("E:\\info.xls"); //使用第一种方法获取并输出 List<List<HashMap<String, Object>>> exceldata = excel.getExcel(file,0,1); if(exceldata!=null){ for(List<HashMap<String, Object>> lista:exceldata){ for(int iii=0;iii<lista.size();iii++){ HashMap<String, Object> hm = lista.get(iii); System.out.print(hm.get(name[iii])+" "); } System.out.println(); } } //使用第二种方法直接获取List<Object> List<Object> list = excel.getExcelObj(file,0,1); for(Object o:list){ TestObj t = (TestObj)o; System.out.println("姓名为:"+t.getName()+",性别:"+t.getSex()+",地址为:"+t.getAddress()+",邮箱为:"+t.getEmail()); } } }
Name | Age | Sex | Birthday | Address | Phone | |
林晚荣 | 20 | 1 | 32502 | 泰山路123号 | [email protected] | 13909909909 |
徐长今 | 16 | 2 | 33605 | 朝鲜大饭店 | [email protected] | 13909909910 |
还有第三行:只在phone的地方有数据。
输出结果
林晚荣 20 男 Tue Dec 27 11:32:02 CST 1988 泰山路123号 [email protected] 1.3909909909E10
徐长今 16 女 Sat Jan 04 11:32:02 CST 1992 朝鲜大饭店 [email protected] 1.390990991E10
null null null null null null 1.3909909911E10
姓名为:林晚荣,性别:男,地址为:泰山路123号,邮箱为:[email protected]
姓名为:徐长今,性别:女,地址为:朝鲜大饭店,邮箱为:[email protected]
姓名为:null,性别:null,地址为:null,邮箱为:null