已整理成完整项目,并进行了优化。看参考地址:
或者
POI 导入篇
1、maven jar 包依赖:
UTF-8 UTF-8 3.12 exceltools org.apache.poi poi ${poi.version} org.apache.poi poi-ooxml ${poi.version} junit junit 3.8.1 test
不用maven的可以自行下载这两个jar包,加入项目中。
2、项目目录树:
3、定义注解类:
(一):ExcelImportCol.java :
/** * @package :com.andy.demo.execltools.imports.annotation * @author :wanglongjie * @createDate :2015年12月2日上午10:44:28 */package com.andy.demo.execltools.imports.annotation;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * 描述:Excel 导入属性注解类 * * 1、导入的类必须添加注解类ExcelImportConfig * 2、该注解类用在类属性上,获取Excel所在列的记录 * * @package :com.andy.demo.execltools.imports.annotation * @file :ExcelImportCol.java * @author :wanglongjie * @createDate :2015年12月2日上午10:44:28 * */@Retention(RetentionPolicy.RUNTIME)@Target({ ElementType.FIELD })public @interface ExcelImportCol { /** * * 描述:Excel 所在列 * * @method :col * @author :wanglongjie * @createDate :2015年12月2日上午10:44:59 * @return Excel 所在列 */ int col();}
(二):ExcelImportConfig.java :
/** * @package :com.andy.demo.execltools.imports.annotation * @author :wanglongjie * @createDate :2015年12月2日上午10:21:11 */package com.andy.demo.execltools.imports.annotation;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * 描述:Excel 导入注解类: * * 1、导入的类必须添加该注解类 * 2、默认从第1行导入 * 3、如果 notNullCols 方法中每一列都为空,则系统认为该条数据不正确,需去除 * * @package :com.andy.demo.execltools.imports.annotation * @file :ExcelImportConfig.java * @author :wanglongjie * @createDate :2015年12月2日上午10:21:11 * */@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)public @interface ExcelImportConfig { /** * * 描述:读取Excel数据记录的开始行,默认为1,即从第1行开始 * * @method :startLine * @author :wanglongjie * @createDate :2015年12月2日上午10:21:48 * @return 有效数据记录的开始行 */ int startLine() default 1; /** * * 描述:读取Excel数据记录非空列索引数组,默认为null,即每一列都可以为空;列索引从0开始 * * 1、如果非空列数组为null,则读取每一行的数据作为一条记录 * 2、如果非空列数组不为null,例如为[0],则若每行的第0列为空,则不读取该行记录;反之读取该行记录 * 3、如果非空列数组不为null,例如为[0,1],则若每行的第0列、第1列同时都为空,则不读取该行记录;反之读取该行记录 * * @method :notNullCols * @author :wanglongjie * @createDate :2015年12月2日上午10:28:57 * @return Excel数据记录非空列索引数组 */ int[] notNullCols() default {};}
3、导入工具类:
/** * @package :com.andy.demo.execltools.imports * @author :wanglongjie * @createDate :2015年12月2日上午10:18:29 */package com.andy.demo.execltools.imports;import java.beans.PropertyDescriptor;import java.io.InputStream;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.math.BigDecimal;import java.util.ArrayList;import java.util.Date;import java.util.List;import org.apache.poi.ss.usermodel.Cell;import org.apache.poi.ss.usermodel.DateUtil;import org.apache.poi.ss.usermodel.Row;import org.apache.poi.ss.usermodel.Sheet;import org.apache.poi.ss.usermodel.Workbook;import org.apache.poi.ss.usermodel.WorkbookFactory;import com.andy.demo.execltools.imports.annotation.ExcelImportCol;import com.andy.demo.execltools.imports.annotation.ExcelImportConfig;/** * 描述: Excel 导入工具类 * * 方法一:excelImport(InputStream, Class) : 将 文件流 转化为 List对象集合,sheet索引默认为0; * 方法一:excelImport(InputStream, Class, int) : 将 文件流 转化为 List对象集合,可设置sheet索引位置 * * @package :com.andy.demo.execltools.imports * @file :ExcelToolsImport.java * @author :wanglongjie * @createDate :2015年12月2日上午10:18:29 */public class ExcelToolsImport { /** * * 描述:获取Excel的载体实体类集合,默认导入Excel的sheet索引值为0 * * @method :excelImport * @author :wanglongjie * @createDate :2015年12月2日上午11:14:59 * @param fileInputStream * :导入Excel生成的文件流 * @param cla * :导入Excel的载体实体类 * @return * @throws Exception */ public staticList excelImport(InputStream fileInputStream, Class cla) throws Exception { return excelImport(fileInputStream, cla, 0); } /** * * 描述:获取Excel的载体实体类集合 * * @method :excelImport * @author :wanglongjie * @createDate :2015年12月2日上午11:08:17 * @param fileInputStream * :导入Excel生成的文件流 * @param cla * :导入Excel的载体实体类 * @param sheetIndex * :导入Excel的sheet索引值 * @return * @throws Exception */ public static List excelImport(InputStream fileInputStream, Class cla, int sheetIndex) throws Exception { checkValidate(fileInputStream, cla); Workbook workbook = WorkbookFactory.create(fileInputStream); Sheet sheet = workbook.getSheetAt(sheetIndex); // 获取最大行和开始行 int rows = sheet.getLastRowNum(); int startLine = getStartLine(cla); List list = new ArrayList (); Row row = null; T t = null; for (int i = startLine; i <= rows; i++) { row = sheet.getRow(i); t = addLine2List(row, cla); if (validateNotNull(t)) { list.add(t); } } return list; } /** * * 描述:读取行,转化为指定的对象 * * @method :addLine2List * @author :wanglongjie * @createDate :2015年12月2日上午11:27:04 * @param row * : Excel Row行对象 * @param cla * :导入Excel的载体实体类 * @return * @throws Exception */ private static T addLine2List(Row row, Class cla) throws Exception { T t = cla.newInstance(); List list = getExcelImportColAnnoFields(cla); for (Field field : list) { setCell2Obj(field, row, t); } return t; } /** * * 描述:读取单元格,设置实体属性值 * * @method :setCell2Obj * @author :wanglongjie * @createDate :2015年12月2日下午12:47:32 * @param field * :实体对象中带有ExcelImportCol注解的属性 * @param row * :Excel Row 行对象 * @param t * :封装的实体对象 * @return * @throws Exception */ private static T setCell2Obj(Field field, Row row, T t) throws Exception { // 获取列索引、单元格 int col = field.getAnnotation(ExcelImportCol.class).col(); Cell cell = row.getCell(col); if (null != cell) { String typeName = field.getType().getSimpleName(); // 获取属性的写入方法 String propertyName = field.getName(); PropertyDescriptor pd = new PropertyDescriptor(propertyName, t.getClass()); Method m = pd.getWriteMethod(); switch (cell.getCellType()) { case Cell.CELL_TYPE_STRING: // 字符串 String value = cell.getRichStringCellValue().getString(); m.invoke(t, value); break; case Cell.CELL_TYPE_NUMERIC: // 数字 | 日期 if (DateUtil.isCellDateFormatted(cell)) { Date date = cell.getDateCellValue(); m.invoke(t, date); } else { double d = cell.getNumericCellValue(); if (BigDecimal.class.getSimpleName().equals(typeName)) { BigDecimal bigDecimal = new BigDecimal(d); m.invoke(t, bigDecimal); } if (Double.class.getSimpleName().equals(typeName) || "double".equals(typeName)) { Double d1 = new Double(d); m.invoke(t, d1); } if (Float.class.getSimpleName().equals(typeName) || "float".equals(typeName)) { Float f = new Float(d); m.invoke(t, f); } if (Integer.class.getSimpleName().equals(typeName) || "int".equals(typeName)) { Integer i = new BigDecimal(d).intValue(); m.invoke(t, i); } if (Long.class.getSimpleName().equals(typeName) || "long".equals(typeName)) { Long l = new BigDecimal(d).longValue(); m.invoke(t, l); } } break; case Cell.CELL_TYPE_BOOLEAN: // boolean 类型 boolean b = cell.getBooleanCellValue(); m.invoke(t, b); break; default: break; } } return t; } /** * * 描述:获取开始行 * * * * @method :getStartLine * @author :wanglongjie * @createDate :2015年12月2日上午10:54:34 * @param cla * :导入Excel的载体实体类 * @return 获取开始行 */ private static int getStartLine(Class cla) { return cla.getAnnotation(ExcelImportConfig.class).startLine(); } /** * * 描述:获取Excel的载体实体类中添加ExcelImportCol注解的属性集合 * * @method :getExcelImportColAnnoFields * @author :wanglongjie * @createDate :2015年12月2日上午10:59:24 * @param cla * :导入Excel的载体实体类 * @return * @throws Exception */ private static List getExcelImportColAnnoFields(Class cla) throws Exception { List fieldList = new ArrayList (); Field[] fields = cla.getDeclaredFields(); for (Field f : fields) { if (f.isAnnotationPresent(ExcelImportCol.class)) { fieldList.add(f); } } return fieldList; } /** * * 描述:验证导入Excel的载体实体类是否合法 * * * * @method :checkValidate * @author :wanglongjie * @createDate :2015年12月2日上午11:01:59 * @param fileInputStream * : 导入Excel生成的文件流 * @param cla * :导入Excel的载体实体类 * @return 验证通过返回 true;验证失败返回 false * @throws Exception */ private static boolean checkValidate(InputStream fileInputStream, Class cla) throws Exception { if (null == fileInputStream) { throw new Exception("导入Excel生成的文件流为空!"); } if (!cla.isAnnotationPresent(ExcelImportConfig.class)) { throw new Exception("指定的实体类" + cla.getName() + " 缺少ExcelImportConfig注解!"); } if (getExcelImportColAnnoFields(cla).size() == 0) { throw new Exception("指定的实体类" + cla.getName() + " 属性缺少ExcelImportCol注解!"); } return true; } /** * * 描述:判断实体对象是否为空(通过 notNullCols() 判断) * * @method :validateNotNull * @author :wanglongjie * @createDate :2015年12月2日下午12:50:25 * @param t * : 实体对象 * @return * @throws Exception */ private static boolean validateNotNull(T t) throws Exception { boolean validate = false; int[] notNullCols = t.getClass().getAnnotation(ExcelImportConfig.class) .notNullCols(); if (null == notNullCols || notNullCols.length == 0) { validate = true; } else { boolean[] b = new boolean[notNullCols.length]; List list = getExcelImportColAnnoFields(t.getClass()); PropertyDescriptor pd = null; Method m = null; Object fieldValue = null; int col = 0; for (int i = 0; i < notNullCols.length; i++) { for (Field f : list) { col = f.getAnnotation(ExcelImportCol.class).col(); // 判断 该列值是否为空 if (notNullCols[i] == col) { pd = new PropertyDescriptor(f.getName(), t.getClass()); m = pd.getReadMethod(); fieldValue = m.invoke(t); if (null == fieldValue) { b[i] = false; } else { b[i] = true; } break; } } } for (int i = 0; i < b.length; i++) { validate = validate || b[i]; } } return validate; }}
已整理成完整项目,并进行了优化。看参考地址:
或者