已整理成完整項目,並進行了優化。看參考地址:java
https://gitee.com/andy_longjie/exceltools 或者 https://github.com/youmulongjie/exceltoolsgit
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <poi.version>3.12</poi.version> <dict>exceltools</dict><!-- 項目名稱 --> </properties> <dependencies> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>${poi.version}</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>${poi.version}</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies>
不用maven的能夠自行下載這兩個jar包,加入項目中。github
/** * @package :com.andy.demo.execltools.imports.annotation<br> * @author :wanglongjie<br> * @createDate :2015年12月2日上午10:44:28<br> */ 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 導入屬性註解類 <br> * <br> * 一、導入的類必須添加註解類ExcelImportConfig<br> * 二、該註解類用在類屬性上,獲取Excel所在列的記錄<br> * * @package :com.andy.demo.execltools.imports.annotation<br> * @file :ExcelImportCol.java<br> * @author :wanglongjie<br> * @createDate :2015年12月2日上午10:44:28<br> * */ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.FIELD }) public @interface ExcelImportCol { /** * * 描述:Excel 所在列 <br> * * @method :col<br> * @author :wanglongjie<br> * @createDate :2015年12月2日上午10:44:59 <br> * @return Excel 所在列 */ int col(); }
/** * @package :com.andy.demo.execltools.imports.annotation<br> * @author :wanglongjie<br> * @createDate :2015年12月2日上午10:21:11<br> */ 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 導入註解類: <br> * <br> * 一、導入的類必須添加該註解類 <br> * 二、默認從第1行導入 <br> * 三、若是 notNullCols 方法中每一列都爲空,則系統認爲該條數據不正確,需去除 <br> * * @package :com.andy.demo.execltools.imports.annotation<br> * @file :ExcelImportConfig.java<br> * @author :wanglongjie<br> * @createDate :2015年12月2日上午10:21:11<br> * */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface ExcelImportConfig { /** * * 描述:讀取Excel數據記錄的開始行,默認爲1,即從第1行開始 <br> * * @method :startLine<br> * @author :wanglongjie<br> * @createDate :2015年12月2日上午10:21:48 <br> * @return 有效數據記錄的開始行 */ int startLine() default 1; /** * * 描述:讀取Excel數據記錄非空列索引數組,默認爲null,即每一列均可覺得空;列索引從0開始<br> * <br> * 一、若是非空列數組爲null,則讀取每一行的數據做爲一條記錄<br> * 二、若是非空列數組不爲null,例如爲[0],則若每行的第0列爲空,則不讀取該行記錄;反之讀取該行記錄<br> * 三、若是非空列數組不爲null,例如爲[0,1],則若每行的第0列、第1列同時都爲空,則不讀取該行記錄;反之讀取該行記錄<br> * * @method :notNullCols<br> * @author :wanglongjie<br> * @createDate :2015年12月2日上午10:28:57 <br> * @return Excel數據記錄非空列索引數組 */ int[] notNullCols() default {}; }
/** * @package :com.andy.demo.execltools.imports<br> * @author :wanglongjie<br> * @createDate :2015年12月2日上午10:18:29<br> */ 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 導入工具類<br> * <br> * 方法一:excelImport(InputStream, Class) : 將 文件流 轉化爲 List對象集合,sheet索引默認爲0;<br> * 方法一:excelImport(InputStream, Class, int) : 將 文件流 轉化爲 List對象集合,可設置sheet索引位置<br> * * @package :com.andy.demo.execltools.imports<br> * @file :ExcelToolsImport.java<br> * @author :wanglongjie<br> * @createDate :2015年12月2日上午10:18:29<br> */ public class ExcelToolsImport { /** * * 描述:獲取Excel的載體實體類集合,默認導入Excel的sheet索引值爲0 <br> * * @method :excelImport<br> * @author :wanglongjie<br> * @createDate :2015年12月2日上午11:14:59 <br> * @param fileInputStream * :導入Excel生成的文件流 * @param cla * :導入Excel的載體實體類 * @return * @throws Exception */ public static <T> List<T> excelImport(InputStream fileInputStream, Class<T> cla) throws Exception { return excelImport(fileInputStream, cla, 0); } /** * * 描述:獲取Excel的載體實體類集合 <br> * * @method :excelImport<br> * @author :wanglongjie<br> * @createDate :2015年12月2日上午11:08:17 <br> * @param fileInputStream * :導入Excel生成的文件流 * @param cla * :導入Excel的載體實體類 * @param sheetIndex * :導入Excel的sheet索引值 * @return * @throws Exception */ public static <T> List<T> excelImport(InputStream fileInputStream, Class<T> 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<T> list = new ArrayList<T>(); 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; } /** * * 描述:讀取行,轉化爲指定的對象 <br> * * @method :addLine2List<br> * @author :wanglongjie<br> * @createDate :2015年12月2日上午11:27:04 <br> * @param row * : Excel Row行對象 * @param cla * :導入Excel的載體實體類 * @return * @throws Exception */ private static <T> T addLine2List(Row row, Class<T> cla) throws Exception { T t = cla.newInstance(); List<Field> list = getExcelImportColAnnoFields(cla); for (Field field : list) { setCell2Obj(field, row, t); } return t; } /** * * 描述:讀取單元格,設置實體屬性值 <br> * * @method :setCell2Obj<br> * @author :wanglongjie<br> * @createDate :2015年12月2日下午12:47:32 <br> * @param field * :實體對象中帶有ExcelImportCol註解的屬性 * @param row * :Excel Row 行對象 * @param t * :封裝的實體對象 * @return * @throws Exception */ private static <T> 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; } /** * * 描述:獲取開始行 * * <br> * * @method :getStartLine<br> * @author :wanglongjie<br> * @createDate :2015年12月2日上午10:54:34 <br> * @param cla * :導入Excel的載體實體類 * @return 獲取開始行 */ private static <T> int getStartLine(Class<T> cla) { return cla.getAnnotation(ExcelImportConfig.class).startLine(); } /** * * 描述:獲取Excel的載體實體類中添加ExcelImportCol註解的屬性集合 <br> * * @method :getExcelImportColAnnoFields<br> * @author :wanglongjie<br> * @createDate :2015年12月2日上午10:59:24 <br> * @param cla * :導入Excel的載體實體類 * @return * @throws Exception */ private static <T> List<Field> getExcelImportColAnnoFields(Class<T> cla) throws Exception { List<Field> fieldList = new ArrayList<Field>(); Field[] fields = cla.getDeclaredFields(); for (Field f : fields) { if (f.isAnnotationPresent(ExcelImportCol.class)) { fieldList.add(f); } } return fieldList; } /** * * 描述:驗證導入Excel的載體實體類是否合法 * * <br> * * @method :checkValidate<br> * @author :wanglongjie<br> * @createDate :2015年12月2日上午11:01:59 <br> * @param fileInputStream * : 導入Excel生成的文件流 * @param cla * :導入Excel的載體實體類 * @return 驗證經過返回 true;驗證失敗返回 false * @throws Exception */ private static <T> boolean checkValidate(InputStream fileInputStream, Class<T> 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() 判斷) <br> * * @method :validateNotNull<br> * @author :wanglongjie<br> * @createDate :2015年12月2日下午12:50:25 <br> * @param t * : 實體對象 * @return * @throws Exception */ private static <T> 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<Field> 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; } }
已整理成完整項目,並進行了優化。看參考地址:apache
https://gitee.com/andy_longjie/exceltools 或者 https://github.com/youmulongjie/exceltools數組