package com.engine.organization.util.excel; import com.engine.salary.util.excel.ExcelParseException; import com.engine.salary.util.excel.ExcelProperty; import com.engine.salary.util.excel.ExcelSupport; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.exception.ContextedRuntimeException; import org.apache.poi.ss.usermodel.Sheet; import org.springframework.web.multipart.MultipartFile; import java.io.InputStream; import java.lang.reflect.Field; import java.math.BigDecimal; import java.util.*; import static com.engine.salary.util.excel.ExcelSupport.EXCEL_TYPE_XLSX; /** * Excel 解析工具类 **/ public class ExcelParseHelper { //待校验的行号 private static final int PARSE_EXCEL_ROW_VALID_CELL_INDEX = 0; //字符开始下标 private static final int CHARACTER_FIRST_INDEX = 0; /** * 将 Excel 解析为 JavaBean 对象 * * @param file excel文件 * @param clazz 解析bean的类 * @param sheetIndex excel中第几个sheet,从0开始 * @param rowIndex 从第几行开始解析,第一行是0 * @param standardCellNum 模板验证,该sheet应有多少列 * @return */ public static List parse2Map(MultipartFile file, Class clazz, int sheetIndex, int rowIndex, int standardCellNum) { List> result = parse2Map(file, sheetIndex, rowIndex, standardCellNum); List list = new ArrayList(); for (List rowDatas : result) { T t = setField(clazz, rowDatas); list.add(t); } return list; } /** * 将 Excel 解析为 JavaBean 对象 * * @param file excel文件 * @param clazz 解析bean的类 * @param sheetIndex excel中第几个sheet,从0开始 * @param rowIndex 从第几行开始解析,第一行是0 * @param standardCellNum 模板验证,该sheet应有多少列 * @param fileName 文件名 * @return */ public static List parse2Map(InputStream file, Class clazz, int sheetIndex, int rowIndex, int standardCellNum, String fileName) { List> result = parse2Map(file, sheetIndex, rowIndex, standardCellNum, fileName); List list = new ArrayList(); for (List rowDatas : result) { T t = setField(clazz, rowDatas); list.add(t); } return list; } /** * 获取excel数据。 * * @param file 文件 * @param sheetIndex 解析第几个sheet * @param rowIndex 从第几行开始解析,第一行为 0,依次类推 * @return 二维数据集合 */ private static List> parse2Map(MultipartFile file, int sheetIndex, int rowIndex, int standardCellNum) { Sheet sheet = ExcelSupport.parseFile(file, sheetIndex); int rowCount = sheet.getPhysicalNumberOfRows(); // 总行数 int cellCount = sheet.getRow(PARSE_EXCEL_ROW_VALID_CELL_INDEX).getPhysicalNumberOfCells(); // 总列数 Validate.isTrue(standardCellNum == cellCount, "Error in excel template! Page %s sheet should have %s column data, existing in %s column , please check the template!", sheetIndex, standardCellNum, cellCount); List> result = new ArrayList>(); for (; rowIndex < rowCount; rowIndex++) { List cellResult = new ArrayList(); for (int j = 0; j < cellCount; j++) { cellResult.add(ExcelSupport.getCellValue(sheet, rowIndex, j)); } result.add(cellResult); } return result; } /** * 获取excel数据。 * * @param file 文件 * @param sheetIndex 解析第几个sheet * @param rowIndex 从第几行开始解析,第一行为 0,依次类推 * @return 二维数据集合 */ private static List> parse2Map(InputStream file, int sheetIndex, int rowIndex, int standardCellNum, String fileName) { Sheet sheet = ExcelSupport.parseFile(file, sheetIndex, fileName); int rowCount = sheet.getPhysicalNumberOfRows(); // 总行数 int cellCount = sheet.getRow(PARSE_EXCEL_ROW_VALID_CELL_INDEX).getPhysicalNumberOfCells(); // 总列数 Validate.isTrue(standardCellNum == cellCount, "Error in excel template! Page %s sheet should have %s column data, existing in %s column , please check the template!", sheetIndex, standardCellNum, cellCount); List> result = new ArrayList>(); for (; rowIndex < rowCount; rowIndex++) { List cellResult = new ArrayList(); for (int j = 0; j < cellCount; j++) { cellResult.add(ExcelSupport.getCellValue(sheet, rowIndex, j)); } result.add(cellResult); } return result; } /** * 将sheet数据转为map * * @param file * @param sheetIndex sheet下标 * @param rowIndex 从哪行开始解析 * @return */ public static List> parse2Map(InputStream file, int sheetIndex, int rowIndex) { Sheet sheet = ExcelSupport.parseFile(file, sheetIndex, EXCEL_TYPE_XLSX); int rowCount = sheet.getPhysicalNumberOfRows(); // 总行数 int cellCount = sheet.getRow(PARSE_EXCEL_ROW_VALID_CELL_INDEX).getPhysicalNumberOfCells(); // 总列数 List sheetHeader = ExcelSupport.getSheetHeader(sheet, PARSE_EXCEL_ROW_VALID_CELL_INDEX); List> result = new ArrayList<>(); for (; rowIndex < rowCount; rowIndex++) { Map cellResult = new HashMap<>(); for (int j = 0; j < cellCount; j++) { String key = sheetHeader.get(j); cellResult.put(key, ExcelSupport.getCellValue(sheet, rowIndex, j)); } result.add(cellResult); } return result; } /** * 将sheet数据转为map * * @param rowIndex 从哪行开始解析 * @return */ public static List> parse2Map(Sheet sheet, int rowIndex) { int rowCount = sheet.getPhysicalNumberOfRows(); // 总行数 int cellCount = sheet.getRow(PARSE_EXCEL_ROW_VALID_CELL_INDEX).getPhysicalNumberOfCells(); // 总列数 List sheetHeader = ExcelSupport.getSheetHeader(sheet, PARSE_EXCEL_ROW_VALID_CELL_INDEX); List> result = new ArrayList<>(); for (; rowIndex < rowCount; rowIndex++) { Map cellResult = new HashMap<>(); for (int j = 0; j < cellCount; j++) { String key = sheetHeader.get(j); cellResult.put(key, ExcelSupport.getCellValue(sheet, rowIndex, j)); } result.add(cellResult); } return result; } /** * 将sheet数据转为List * * @param rowIndex 从哪行开始解析 * @return */ public static List> parse2List(Sheet sheet, int rowIndex) { int rowCount = sheet.getPhysicalNumberOfRows(); // 总行数 int cellCount = sheet.getRow(PARSE_EXCEL_ROW_VALID_CELL_INDEX).getPhysicalNumberOfCells(); // 总列数 List> result = new ArrayList>(); for (; rowIndex < rowCount; rowIndex++) { List cellResult = new ArrayList(); for (int j = 0; j < cellCount; j++) { cellResult.add(ExcelSupport.getCellValue(sheet, rowIndex, j)); } result.add(cellResult); } return result; } /** * 为对象的每一个属性赋值 * * @param clazz * @param rowDatas * @param * @return */ private static T setField(Class clazz, List rowDatas) { try { T obj = clazz.newInstance(); Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class); if (excelProperty == null) { continue; } int index = excelProperty.index(); Object value = getFieldValue(field, rowDatas.get(index), excelProperty); field.setAccessible(true); field.set(obj, value); } return obj; } catch (Exception e) { throw new ExcelParseException(e.getMessage(), e); } } /** * 获取javaBean属性值 * * @param field javaBean的对象属性 * @param value excel中对应的值 * @param excelProperty javaBean中解析excel注解,包含日期格式、错误提示信息 * @return */ @SuppressWarnings("rawtypes") private static Object getFieldValue(Field field, String value, ExcelProperty excelProperty) { if (StringUtils.isEmpty(value)) { return null; } Object val = null; try { Class typeClass = field.getType(); if (typeClass == Integer.class) { val = Integer.valueOf(value); } else if (typeClass == Long.class) { val = Long.valueOf(value); } else if (typeClass == Float.class) { val = Float.valueOf(value); } else if (typeClass == Double.class) { val = Double.valueOf(value); } else if (typeClass == Date.class) { val = ExcelSupport.getDate(value, excelProperty.format()); } else if (typeClass == Short.class) { val = Short.valueOf(value); } else if (typeClass == Character.class) { val = value.charAt(CHARACTER_FIRST_INDEX); } else if (typeClass == BigDecimal.class) { val = new BigDecimal(value); } else { val = value; } } catch (Exception e) { throw new ContextedRuntimeException(excelProperty.msg(), e); } return val; } }