poi 工具类:
public class PoiUtil { /** * 导入xlsx格式的excel文件 * @param in * @param entityClass * @param fieldMap * @param* @return * @throws Exception */ public static List xlsxToList(InputStream in, Class entityClass, Map fieldMap,Integer num) throws Exception { // 定义要返回的list List resultList = new ArrayList (); org.apache.poi.ss.usermodel.Workbook wb = new XSSFWorkbook(in); int sheetSIze = wb.getNumberOfSheets(); for (int j = 0; j< sheetSIze;j++) { if (j!=num){ continue; } org.apache.poi.ss.usermodel.Sheet sheet = wb.getSheetAt(j); Row firstRow = sheet.getRow(2); int columnSize = firstRow.getLastCellNum(); String[] excelFieldNames = new String[columnSize]; // 获取Excel中的列名 for (int i = 0; i < columnSize; i++) { if(firstRow.getCell(i) != null){ firstRow.getCell(i).setCellType(XSSFCell.CELL_TYPE_STRING); excelFieldNames[i] = firstRow.getCell(i).getStringCellValue(); } } // 判断需要的字段在Excel中是否都存在 boolean isExist = true; String lackName = null; List excelFieldList = Arrays.asList(excelFieldNames); for (String cnName : fieldMap.values()) { if (!excelFieldList.contains(cnName)) { lackName = cnName; isExist = false; break; } } // 如果有列名不存在,则抛出异常,提示错误 if (!isExist) { // throw new ServiceException("Excel中缺少必要的字段:" + lackName); throw new Exception("Excel中缺少必要的字段:" + lackName); } // 将列名和列号放入Map中,这样通过列名就可以拿到列号 LinkedHashMap colMap = new LinkedHashMap (); for (int i = 0; i < excelFieldNames.length; i++) { colMap.put(excelFieldNames[i], firstRow.getCell(i).getColumnIndex()); } // 将sheet转换为list, rowNum从0开始, 总数 = lastNum + 1 int rowCounts = sheet.getLastRowNum() + 1; for (int i = 3; i < rowCounts; i++) { // 新建要转换的对象 T entity = entityClass.newInstance(); Row row = sheet.getRow(i); //避免空行 if(row == null){ continue; } // 给对象中的字段赋值 for (Entry entry : fieldMap.entrySet()) { // 获取英文字段名 String enNormalName = entry.getKey(); // 获取中文字段名 String cnNormalName = entry.getValue(); // 根据中文字段名获取列号 int col = colMap.get(cnNormalName); String content = null; // 获取当前单元格中的内容 if(row.getCell(col) != null){ row.getCell(col).setCellType(XSSFCell.CELL_TYPE_STRING); content = row.getCell(col, Row.CREATE_NULL_AS_BLANK).getStringCellValue(); } // 给对象赋值 setFieldValueByName(enNormalName, content, entity); } resultList.add(entity); } } return resultList; } /** * @MethodName : getFieldByName * @Description : 根据字段名获取字段 * @param fieldName * 字段名 * @param clazz * 包含该字段的类 * @return 字段 */ private static Field getFieldByName(String fieldName, Class> clazz) { // 拿到本类的所有字段 Field[] selfFields = clazz.getDeclaredFields(); // 如果本类中存在该字段,则返回 for (Field field : selfFields) { if (field.getName().equals(fieldName)) { return field; } } // 否则,查看父类中是否存在此字段,如果有则返回 Class> superClazz = clazz.getSuperclass(); if (superClazz != null && superClazz != Object.class) { return getFieldByName(fieldName, superClazz); } // 如果本类和父类都没有,则返回空 return null; } /** * @MethodName : setFieldValueByName * @Description : 根据字段名给对象的字段赋值 * @param fieldName * 字段名 * @param fieldValue * 字段值 * @param o * 对象 */ private static void setFieldValueByName(String fieldName, Object fieldValue, Object o) throws Exception { if(fieldValue == null){ return; } Field field = getFieldByName(fieldName, o.getClass()); if (field != null) { field.setAccessible(true); // 获取字段类型 Class> fieldType = field.getType(); //trim一下防止类型转换时报错 String fieldValueStr = fieldValue.toString().trim(); // 根据字段类型给字段赋值 if (String.class == fieldType) { field.set(o, fieldValueStr); } else if ((Integer.TYPE == fieldType) || (Integer.class == fieldType)) { field.set(o, Integer.parseInt(fieldValueStr)); } else if ((Long.TYPE == fieldType) || (Long.class == fieldType)) { field.set(o, Long.valueOf(fieldValueStr)); } else if ((Float.TYPE == fieldType) || (Float.class == fieldType)) { field.set(o, Float.valueOf(fieldValueStr)); } else if ((Short.TYPE == fieldType) || (Short.class == fieldType)) { field.set(o, Short.valueOf(fieldValueStr)); } else if ((Double.TYPE == fieldType) || (Double.class == fieldType)) { field.set(o, Double.valueOf(fieldValueStr)); } else if (Character.TYPE == fieldType) { if (fieldValue.toString().length() > 0) { field.set(o, fieldValue.toString().charAt(0)); } } else if (Date.class == fieldType) { field.set(o, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") .parse(fieldValueStr)); } else { field.set(o, fieldValue); } } else { throw new Exception(o.getClass().getSimpleName() + "类不存在字段名 " + fieldName); } } }
controller 层测试
@RestController @Slf4j @RequestMapping(value = "/excel") public class ExcelTestContrller { /** * Description:上次excel 转对象 */ @RequestMapping(value = "/test") public void getClassify(@RequestParam(value = "file", required = false) MultipartFile file) { // key:封装的对象属性名 value:excel列名 // sheet1 MapfieldMap1 = new HashMap<>(); fieldMap1.put("name1", "站址类型"); fieldMap1.put("name2", "频点类别"); fieldMap1.put("name3", "扇区配置"); Map fieldMap2 = new HashMap<>(); // sheet2 fieldMap2.put("name1", "站址类型"); fieldMap2.put("name2", "频点类别"); fieldMap2.put("name3", "扇区配置"); try { // 读第几个sheet num就传几 List list1 = PoiUtil.xlsxToList(file.getInputStream(), Sheet1.class, fieldMap1,1); List list2 = PoiUtil.xlsxToList(file.getInputStream(), Sheet2.class, fieldMap2,2); List
pojo类:
@Data @Builder @AllArgsConstructor @NoArgsConstructor public class Sheet1 { private String name1; private String name2; private String name3; }
@Data @Builder @AllArgsConstructor @NoArgsConstructor public class Sheet2 { private String name1; private String name2; private String name3; }
application.yml 配置:
#文件大小 MB必须大写 # maxFileSize 是单个文件大小 # maxRequestSize是设置总上传的数据大小 spring: servlet: multipart: enabled: true max-file-size: 100MB max-request-size: 1000MB
pom.xml 配置:
org.apache.poi poi 3.9 org.apache.poi poi-ooxml 3.9 org.apache.poi poi-ooxml-schemas 3.9
net.sourceforge.jexcelapi jxl 2.6.12 log4j log4j