我是靠谱客的博主 等待老虎,这篇文章主要介绍基于 Java 泛型和反射 导入 Excel,现在分享给大家,希望可以做个参考。

1,数据迁移,存量备份等功能会有Excel批量导入。如果针对每个excel都做相应的POI解析,并调用javabean的set方法生成事例无疑,将会浪费大量工作量。

本篇文章基于Java泛型和反射技术,封装POI,对excel解析,生成javabean。SpringBoot做TDD

Maven Dependency

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.3.RELEASE</version> </parent> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-base</artifactId> <version>3.0.3</version> </dependency> <dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-web</artifactId> <version>3.0.3</version> </dependency> <dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-annotation</artifactId> <version>3.0.3</version> </dependency>

直接搞代码

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

@SuppressWarnings(“hiding”)
public class ExcelUtil2 {

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
private Workbook workbook; public List<T> importExcel(String sheetName, File f, Class<T> item) { List<T> list = null; try { if(f.getName().endsWith("xlsx")){ workbook = new XSSFWorkbook(new FileInputStream(f)); }else{ workbook = new HSSFWorkbook(new FileInputStream(f)); } Sheet sheet = workbook.getSheet(sheetName); if (!"".equals(sheetName.trim())) { sheet = workbook.getSheet(sheetName);// 如果指定sheet名,则取指定sheet中的内容. } if (sheet == null) { sheet = workbook.getSheetAt(0); // 如果传入的sheet名不存在则默认指向第1个sheet. } // 获取数据 list = dispatch(sheet, item); } catch (IOException e) { e.printStackTrace(); } return list; } /** 生成实体类的 List<T> * 由于采取反射技术,所以要传入 实体类的类型 ,例如Entity.class * */ public List<T> dispatch(Sheet sheet, Class<T> clazz) { List<T> instances = new ArrayList<>(); List<Map<String, String>> sheetValue = parseExcelSheet(sheet); for (int i = 0; i < sheetValue.size(); i++) { Map<String, String> map = sheetValue.get(i); Field[] fields = clazz.getDeclaredFields(); try { T t2 = clazz.newInstance(); for (Field field : fields) { field.setAccessible(true); Type type = field.getType(); field.set(t2, getTypeValue(map.get(field.getName()), type.getTypeName())); } instances.add(t2); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } } return instances; } //赋值判断类型 public Object getTypeValue(String value, String type) { Object obj = new Object(); if ("int".equals(type) || type.indexOf("Integer") > -1) { obj = Integer.valueOf(value); } else if ("short".equals(type) || type.indexOf("Short") > -1) { obj = Short.valueOf(value); } else if ("long".equals(type) || type.indexOf("Long") > -1) { obj = Long.valueOf(value); } else if ("float".equals(type) || type.indexOf("Float") > -1) { obj = Float.valueOf(value); } else if ("double".equals(type) || type.indexOf("Double") > -1) { obj = Double.valueOf(value); } else if ("boolean".equals(type) || type.indexOf("Boolean") > -1) { obj = Boolean.valueOf(value); } else { obj = value; } return obj; } /** * 解析Excel第一行,并生成以第一行表头为key,每一行的值为value的map * 例如: excel内容如下 * id alarm 1 abcd1 2 abcd2 3 abcd3 那么List<Map>就是的内容就是 List: map1( id: 1, alarm: abcd1 ),map2(( id: 2, alarm: abcd2 )..... */ public List<Map<String, String>> parseExcelSheet(Sheet sheet) { List<Map<String, String>> result = new ArrayList<>(); Map<String, String> rowValue = null; int rows = sheet.getPhysicalNumberOfRows(); String[] headers = getHeaderValue(sheet.getRow(0)); for (int i = 1; i < rows; i++) { rowValue = new HashMap<>(); Row row = sheet.getRow(i); for (int kk = 0; kk < headers.length; kk++) { rowValue.put(headers[kk], String.valueOf(getCellValue(row.getCell(kk)))); } result.add(rowValue); } return result; } /** 获取第一行,表头,也就是实体类的字段,支持中英文,及下划线,忽略大小写,但是绝笔不能重复,表头有重复字段则不能解析 **/ private String[] getHeaderValue(Row rowHeader) { int colNum = rowHeader.getPhysicalNumberOfCells(); String[] headValue = new String[rowHeader.getPhysicalNumberOfCells()]; for (int i = 0; i < colNum; i++) { headValue[i] = rowHeader.getCell(i).getStringCellValue(); } return headValue; } @SuppressWarnings("deprecation") public Object getCellValue(Cell cell) { Object value = null; switch (cell.getCellType()) { case Cell.CELL_TYPE_NUMERIC: // 数字 // 如果为时间格式的内容 if (DateUtil.isCellDateFormatted(cell)) { // 注:format格式 yyyy-MM-dd hh:mm:ss // 中小时为12小时制,若要24小时制,则把小h变为H即可,yyyy-MM-dd HH:mm:ss SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd hh:mm:ss"); value = sdf.format( DateUtil.getJavaDate(cell.getNumericCellValue())).toString(); break; } else { value = new DecimalFormat("0").format(cell.getNumericCellValue()); } break; case Cell.CELL_TYPE_STRING: // 字符串 value = cell.getStringCellValue(); break; case Cell.CELL_TYPE_BOOLEAN: // Boolean value = cell.getBooleanCellValue() + ""; break; case Cell.CELL_TYPE_FORMULA: // 公式 value = cell.getCellFormula() + ""; break; case Cell.CELL_TYPE_BLANK: // 空值 value = ""; break; case Cell.CELL_TYPE_ERROR: // 故障 value = "非法字符"; break; default: value = "未知类型"; break; } return value; }

}

实体类
public class Alarm implements Serializable {

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/** */ private int id; /** */ private String alarm; /** * 获取 主键 */ public int getId() { return id; } /** * 设置 主键 */ public void setId(int id) { this.id = id; } /** * 获取 */ public String getAlarm() { return alarm; } /** * 设置 */ public void setAlarm(String alarm) { this.alarm = alarm; } @Override public String toString() { return "Alarm [id=" + id + ", alarm=" + alarm + "]"; }

}

测试代码

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
@Test public void testImport() { ExcelUtil2<Alarm> excelUtil = new ExcelUtil2<>() ; //"alarm"为excel 的 sheet名字,也就是表名,暂时未做批量功能 List<Alarm> acfForms = excelUtil.importExcel("alarm", new File(path) , Alarm.class); for (Alarm a : acfForms) { System.out.println(a.toString()); } }

表格
id alarm
1 abcd1
2 abcd2
3 abcd3
4 abcd4
5 abcd5
6 abcd6
7 abcd7

最后

以上就是等待老虎最近收集整理的关于基于 Java 泛型和反射 导入 Excel的全部内容,更多相关基于内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(77)

评论列表共有 0 条评论

立即
投稿
返回
顶部