You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
weaver-hrm-organization/src/com/engine/organization/util/excel/ExcelParseHelper.java

266 lines
10 KiB
Java

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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 <T> List<T> parse2Map(MultipartFile file, Class<T> clazz, int sheetIndex, int rowIndex, int standardCellNum) {
List<List<String>> result = parse2Map(file, sheetIndex, rowIndex, standardCellNum);
List<T> list = new ArrayList<T>();
for (List<String> 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 <T> List<T> parse2Map(InputStream file, Class<T> clazz, int sheetIndex, int rowIndex, int standardCellNum, String fileName) {
List<List<String>> result = parse2Map(file, sheetIndex, rowIndex, standardCellNum, fileName);
List<T> list = new ArrayList<T>();
for (List<String> rowDatas : result) {
T t = setField(clazz, rowDatas);
list.add(t);
}
return list;
}
/**
* <strong>获取excel数据。</strong>
*
* @param file 文件
* @param sheetIndex 解析第几个sheet
* @param rowIndex 从第几行开始解析,第一行为 0依次类推
* @return 二维数据集合
*/
private static List<List<String>> 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<List<String>> result = new ArrayList<List<String>>();
for (; rowIndex < rowCount; rowIndex++) {
List<String> cellResult = new ArrayList<String>();
for (int j = 0; j < cellCount; j++) {
cellResult.add(ExcelSupport.getCellValue(sheet, rowIndex, j));
}
result.add(cellResult);
}
return result;
}
/**
* <strong>获取excel数据。</strong>
*
* @param file 文件
* @param sheetIndex 解析第几个sheet
* @param rowIndex 从第几行开始解析,第一行为 0依次类推
* @return 二维数据集合
*/
private static List<List<String>> 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<List<String>> result = new ArrayList<List<String>>();
for (; rowIndex < rowCount; rowIndex++) {
List<String> cellResult = new ArrayList<String>();
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<Map<String, Object>> 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<String> sheetHeader = ExcelSupport.getSheetHeader(sheet, PARSE_EXCEL_ROW_VALID_CELL_INDEX);
List<Map<String, Object>> result = new ArrayList<>();
for (; rowIndex < rowCount; rowIndex++) {
Map<String, Object> 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<Map<String, Object>> parse2Map(Sheet sheet, int rowIndex) {
int rowCount = sheet.getPhysicalNumberOfRows(); // 总行数
int cellCount = sheet.getRow(PARSE_EXCEL_ROW_VALID_CELL_INDEX).getPhysicalNumberOfCells(); // 总列数
List<String> sheetHeader = ExcelSupport.getSheetHeader(sheet, PARSE_EXCEL_ROW_VALID_CELL_INDEX);
List<Map<String, Object>> result = new ArrayList<>();
for (; rowIndex < rowCount; rowIndex++) {
Map<String, Object> 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<List<String>> parse2List(Sheet sheet, int rowIndex) {
int rowCount = sheet.getPhysicalNumberOfRows(); // 总行数
int cellCount = sheet.getRow(PARSE_EXCEL_ROW_VALID_CELL_INDEX).getPhysicalNumberOfCells(); // 总列数
List<List<String>> result = new ArrayList<List<String>>();
for (; rowIndex < rowCount; rowIndex++) {
List<String> cellResult = new ArrayList<String>();
for (int j = 0; j < cellCount; j++) {
cellResult.add(ExcelSupport.getCellValue(sheet, rowIndex, j));
}
result.add(cellResult);
}
return result;
}
/**
* 为对象的每一个属性赋值
*
* @param clazz
* @param rowDatas
* @param <T>
* @return
*/
private static <T> T setField(Class<T> clazz, List<String> 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);
}
}
/**
* <strong>获取javaBean属性值</strong>
*
* @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;
}
}