1. 任务描述
在Excel文件中获取员工的薪资、公积金等信息,经过计算后输出每个员工的薪资、个税等情况至目标Excel文件
2. 核心技术点
-
使用注解标记每个属性在Excel表格中的位置
-
使用反射将Excel表格中的信息读取至内存中
-
使用POI读取Excel表格
-
使用maven插件实现jar包的生成
3. 实现方法
(1)注解:MyAnn
标注了属性的类型,包括了基本信息、工资信息、普通输入信息、输出信息,此外还标注了属性在Excel表格中的位置,用于读取不同列数的信息。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MyAnn {
int type();
int columnNum();
String name();
}
(2)读取Excel类:ReadExcel
用于将输入的Excel文件逐行读取下来,并通过反射的方法保存于内存中,以进行下一步的输出。
public class ReadExcel {
public static <T> List<T> readExcel(File file, Class<T> clazz) throws Exception {
List<T> list = new ArrayList<>();
File mainFile = new File(file, "/员工五险一金申报表.xlsx");
XSSFWorkbook mainExcelFile = new XSSFWorkbook(new FileInputStream(mainFile));
XSSFSheet mainSheet = mainExcelFile.getSheetAt(0);
XSSFRow row = null;
MyAnn myAnn = null;
XSSFCell cell = null;
int index = 0;
int departmentNum = 0;
XSSFSheet[][] monthsSheet = getMonthsSheet(file);
int[] rowNum = new int[4];
int rowSum = mainSheet.getLastRowNum();
Field[] fields = clazz.getDeclaredFields();
for (int i = 1; i <= rowSum; i++) {
try {
Constructor constructor = clazz.getConstructor();
T obj = (T) constructor.newInstance();
for (Field field : fields) {
field.setAccessible(true);
if (field.isAnnotationPresent(MyAnn.class)) {
myAnn = field.getAnnotation(MyAnn.class);
if (myAnn.type() == Person.OUTPUT_FILE) {
continue;
}
index = myAnn.columnNum();
if (myAnn.type() == Person.SALARY_FILE) {
double[] data = new double[Person.monthNum];
for (int j = 0; j < Person.monthNum; j++) {
row = monthsSheet[j][departmentNum].getRow(rowNum[departmentNum]);
cell = row.getCell(index);
cell.setCellType(CellType.STRING);
String value = cell.getStringCellValue();
data[j] = Double.parseDouble(value);
}
field.set(obj, data);
} else {
row = mainSheet.getRow(i);
cell = row.getCell(index);
cell.setCellType(CellType.STRING);
String value = cell.getStringCellValue();
setField(field, obj, value);
if (field.getName().equals("department")) {
clazz.getDeclaredMethod("setDepartmentNum").invoke(obj);