首页 > 编程 > Java > 正文

java利用注解实现简单的excel数据读取

2019-11-26 11:56:34
字体:
来源:转载
供稿:网友

实现工具类

利用注解实现简单的excel数据读取,利用注解对类的属性和excel中的表头映射,使用Apache的poi就不用在业务代码中涉及row,rows这些属性了。

定义注解:

@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.FIELD)public @interface Excel {  String name();}

由于本例中只涉及根据Excel表头部分对Excel进行解析,只定义了一个name作为和Excel表头的隐射。

工具类完整代码如下:

public class ExcelUtil<T> { Class<T> clazz; public ExcelUtil(Class<T> clazz) {  this.clazz = clazz; } public List<T> importExcel(String sheetName, InputStream input) {  int maxCol = 0;  List<T> list = new ArrayList<T>();  try {   Workbook workbook = WorkbookFactory.create(input);   Sheet sheet = workbook.getSheet(sheetName);   // 如果指定sheet名,则取指定sheet中的内容.   if (!sheetName.trim().equals("")) {    sheet = workbook.getSheet(sheetName);   }   // 如果传入的sheet名不存在则默认指向第1个sheet.   if (sheet == null) {    sheet = workbook.getSheetAt(0);   }   int rows = sheet.getPhysicalNumberOfRows();   // 有数据时才处理   if (rows > 0) {    List<Field> allFields = getMappedFiled(clazz, null);    // 定义一个map用于存放列的序号和field.    Map<Integer, Field> fieldsMap = new HashMap<Integer, Field>();    // 第一行为表头    Row rowHead = sheet.getRow(0);    Map<String, Integer> cellMap = new HashMap<>();    int cellNum = rowHead.getPhysicalNumberOfCells();    for (int i = 0; i < cellNum; i++){     cellMap.put(rowHead.getCell(i).getStringCellValue().toLowerCase(), i);    }    for (Field field : allFields) {     // 将有注解的field存放到map中.     if (field.isAnnotationPresent(Excel.class)) {      Excel attr = field.getAnnotation(Excel.class);      // 根据Name来获取相应的failed      int col = cellMap.get(attr.name().toLowerCase());      field.setAccessible(true);      fieldsMap.put(col, field);     }    }    // 从第2行开始取数据    for (int i = 1; i < rows; i++) {     Row row = sheet.getRow(i);     T entity = null;     for (int j = 0; j < cellNum; j++) {      Cell cell = row.getCell(j);      if (cell == null) {       continue;      }      int cellType = cell.getCellType();      String c = "";      if (cellType == HSSFCell.CELL_TYPE_NUMERIC) {       DecimalFormat df = new DecimalFormat("0");       c = df.format(cell.getNumericCellValue());      } else if (cellType == HSSFCell.CELL_TYPE_BOOLEAN) {       c = String.valueOf(cell.getBooleanCellValue());      } else {       c = cell.getStringCellValue();      }      if (c == null || c.equals("")) {       continue;      }      entity = (entity == null ? clazz.newInstance() : entity);      // 从map中得到对应列的field.      Field field = fieldsMap.get(j);      if (field == null) {       continue;      }      // 取得类型,并根据对象类型设置值.      Class<?> fieldType = field.getType();      if (String.class == fieldType) {       field.set(entity, String.valueOf(c));      } else if ((Integer.TYPE == fieldType)        || (Integer.class == fieldType)) {       field.set(entity, Integer.valueOf(c));      } else if ((Long.TYPE == fieldType)        || (Long.class == fieldType)) {       field.set(entity, Long.valueOf(c));      } else if ((Float.TYPE == fieldType)        || (Float.class == fieldType)) {       field.set(entity, Float.valueOf(c));      } else if ((Short.TYPE == fieldType)        || (Short.class == fieldType)) {       field.set(entity, Short.valueOf(c));      } else if ((Double.TYPE == fieldType)        || (Double.class == fieldType)) {       field.set(entity, Double.valueOf(c));      } else if (Character.TYPE == fieldType) {       if (c.length() > 0) {        field.set(entity, c.charAt(0));       }      }     }     if (entity != null) {      list.add(entity);     }    }   }  } catch (Exception e) {   e.printStackTrace();  }  return list; } /**  * 得到实体类所有通过注解映射了数据表的字段  *  * @param clazz  * @param fields  * @return  */ private List<Field> getMappedFiled(Class clazz, List<Field> fields) {  if (fields == null) {   fields = new ArrayList<Field>();  }  // 得到所有定义字段  Field[] allFields = clazz.getDeclaredFields();  // 得到所有field并存放到一个list中.  for (Field field : allFields) {   if (field.isAnnotationPresent(Excel.class)) {    fields.add(field);   }  }  if (clazz.getSuperclass() != null    && !clazz.getSuperclass().equals(Object.class)) {   getMappedFiled(clazz.getSuperclass(), fields);  }  return fields; }}

代码很简单,获取sheet,解析第一行,并和实体类标有注解的字段一一对应,用hashMap记录下来,然后循环取得Excel中剩下所有的数据,根据map的对应关系将值set到对应字段。

基本使用

待解析表格如下:

定义实体类:

public class User { @Excel(name = "filed1") private String name; @Excel(name = "filed2") private String nameEn; @Excel(name = "filed3") private Integer age; @Excel(name = "filed4") private String six; @Excel(name = "filed5") private String weight; // ...getter setter}

使用工具类:

public static void main (String[] args) { FileInputStream fileInputStream = null; try {  fileInputStream = new FileInputStream("D://data.xlsx"); } catch (FileNotFoundException e) {  e.printStackTrace(); } ExcelUtil<User> util = new ExcelUtil<>(User.class); List<User> jalanHotelList = util.importExcel("user", fileInputStream); // do something}

利用这个思路可以扩展出导出excel功能,利用注解指定导出的excel表头,甚至可以轻松控制excel表头的颜色,合并属性等等,在xdemo中有详细复杂的示例,可以研究下。由于我的需求很简单,就不整那么复杂啦。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表