SpringBoot:Excel文件解析

SpringBoot:上传Excel文件并转换成javabean保存到数据库

pom.xml引入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!-- 提供API给Java程式对Microsoft Office格式档案读和写的功能 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.13</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.13</version>
</dependency>

<!-- 上传文件需要的依赖 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package com.fufu.config.excel;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Excel注解,用以生成Excel表格文件
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE})
public @interface Excel {

/**
* 列名
* @return
*/
String name() default "";

/**
* 宽度
* @return
*/
int width() default 20;

/**
* 忽略该字段
* @return
*/
boolean skip() default false;

/**
* 日期格式 默认yyyy-MM-dd HH:mm:ss
* @return
*/
String dateFormat() default "yyyy-MM-dd HH:mm:ss";

/**
* 浮点数的精度
* @return
*/
int precision() default -1;

/**
* 四舍五入
* @return
*/
boolean round() default true;

}
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
package com.fufu.config.excel;

import java.util.HashMap;
import java.util.Map;

/**
* Excel导入导出数据定义转换<br>
* 举例:<br>
* 数据导出, {lock,{0:正常,1:锁定}}<br>
* 数据导入,{lock,{正常:0,锁定:1}}
*/
public class ExcelDataFormatter {
/**
* K:{V1:V2}
*/
private Map<String,Map<String,String>> formatter=new HashMap<String, Map<String,String>>();

public void set(String key, Map<String,String> map){
formatter.put(key, map);
}

public Map<String,String> get(String key){
return formatter.get(key);
}

}
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
package com.fufu.config.excel;

import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
* Excel内容转化成Bean
*/
public class ExcelToBean {

private static int etimes = 0;


/**
* 从文件读取数据,最好是所有的单元格都是文本格式,日期格式要求yyyy-MM-dd HH:mm:ss,布尔类型0:真,1:假
*
* @param edf
* 数据格式化
*
* @param file
* Excel文件,支持xlsx后缀,xls的没写,基本一样
* @return
* @throws Exception
*/
@SuppressWarnings("unchecked")
public static <E> List<E> readFromFile(ExcelDataFormatter edf, InputStream is, Class<?> clazz) throws Exception {
Field[] fields = ReflectionUtils.getClassFieldsAndSuperClassFields(clazz);

Map<String, String> textToKey = new HashMap<String, String>();

Excel _excel = null;
for (Field field : fields) {
_excel = field.getAnnotation(Excel.class);
if (_excel == null || _excel.skip() == true) {
continue;
}
textToKey.put(_excel.name(), field.getName());
}

Workbook wb = new XSSFWorkbook(is);

Sheet sheet = wb.getSheetAt(0);
Row title = sheet.getRow(0);
// 标题数组,后面用到,根据索引去标题名称,通过标题名称去字段名称用到 textToKey
String[] titles = new String[title.getPhysicalNumberOfCells()];
for (int i = 0; i < title.getPhysicalNumberOfCells(); i++) {
titles[i] = title.getCell(i).getStringCellValue();
}

List<E> list = new ArrayList<E>();

E e = null;

int rowIndex = 0;
int columnCount = titles.length;
Cell cell = null;
Row row = null;

for (Iterator<Row> it = sheet.rowIterator(); it.hasNext();) {

row = it.next();
if (rowIndex++ == 0) {
continue;
}

if (row == null) {
break;
}

e = (E)clazz.newInstance();

for (int i = 0; i < columnCount; i++) {
cell = row.getCell(i);
etimes = 0;
readCellContent(textToKey.get(titles[i]), fields, cell, e, edf);
}
list.add(e);
}
return list;
}

/**
* 从单元格读取数据,根据不同的数据类型,使用不同的方式读取<br>
* 有时候POI自作聪明,经常和我们期待的数据格式不一样,会报异常,<br>
* 我们这里采取强硬的方式<br>
* 使用各种方法,知道尝试到读到数据为止,然后根据Bean的数据类型,进行相应的转换<br>
* 如果尝试完了(总共7次),还是不能得到数据,那么抛个异常出来,没办法了
*
* @param key
* 当前单元格对应的Bean字段
* @param fields
* Bean所有的字段数组
* @param cell
* 单元格对象
* @param obj
* @throws Exception
*/
public static void readCellContent(String key, Field[] fields, Cell cell, Object obj, ExcelDataFormatter edf) throws Exception {

Object o = null;
try {
switch (cell.getCellType()) {
case XSSFCell.CELL_TYPE_BOOLEAN:
o = cell.getBooleanCellValue();
break;
case XSSFCell.CELL_TYPE_NUMERIC:
o = cell.getNumericCellValue();
NumberFormat nf = NumberFormat.getInstance();
String s = nf.format(o);
if (s.indexOf(",") >= 0) {
s = s.replace(",", "");
}
o = s;
if (HSSFDateUtil.isCellDateFormatted(cell)) {
o = DateUtil.getJavaDate(cell.getNumericCellValue());
}
break;
case XSSFCell.CELL_TYPE_STRING:
o = cell.getStringCellValue();
break;
case XSSFCell.CELL_TYPE_ERROR:
o = cell.getErrorCellValue();
break;
case XSSFCell.CELL_TYPE_BLANK:
o = null;
break;
case XSSFCell.CELL_TYPE_FORMULA:
o = cell.getCellFormula();
break;
default:
o = null;
break;
}

if (o == null)
return;

for (Field field : fields) {
field.setAccessible(true);
if (field.getName().equals(key)) {
Boolean bool = true;
Map<String, String> map = null;
if (edf == null) {
bool = false;
} else {
map = edf.get(field.getName());
if (map == null) {
bool = false;
}
}

if (field.getType().equals(Date.class)) {
if (o.getClass().equals(Date.class)) {
field.set(obj, o);
} else {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
field.set(obj, sdf.parse(o.toString()));
}
} else if (field.getType().equals(String.class)) {
if (o.getClass().equals(String.class)) {
field.set(obj, o);
} else {
field.set(obj, o.toString());
}
} else if (field.getType().equals(Long.class)) {
if (o.getClass().equals(Long.class)) {
field.set(obj, o);
} else {
field.set(obj, Long.parseLong(o.toString()));
}
} else if (field.getType().equals(Integer.class)) {
if (o.getClass().equals(Integer.class)) {
field.set(obj, o);
} else {
// 检查是否需要转换
if (bool) {
field.set(obj, map.get(o.toString()) != null ? Integer.parseInt(map.get(o.toString())) : Integer.parseInt(o.toString()));
} else {
if(!o.getClass().equals(Double.class))
field.set(obj, Integer.parseInt(o.toString()));
else
field.set(obj, Integer.parseInt(new java.text.DecimalFormat("0").format(o)));
}

}
} else if (field.getType().equals(BigDecimal.class)) {
if (o.getClass().equals(BigDecimal.class)) {
field.set(obj, o);
} else {
field.set(obj, BigDecimal.valueOf(Double.parseDouble(o.toString())));
}
} else if (field.getType().equals(Boolean.class)) {
if (o.getClass().equals(Boolean.class)) {
field.set(obj, o);
} else {
// 检查是否需要转换
if (bool) {
field.set(obj, map.get(o.toString()) != null ? Boolean.parseBoolean(map.get(o.toString())) : Boolean.parseBoolean(o.toString()));
} else {
field.set(obj, Boolean.parseBoolean(o.toString()));
}
}
} else if (field.getType().equals(Float.class)) {
if (o.getClass().equals(Float.class)) {
field.set(obj, o);
} else {
field.set(obj, Float.parseFloat(o.toString()));
}
} else if (field.getType().equals(Double.class)) {
if (o.getClass().equals(Double.class)) {
field.set(obj, o);
} else {
field.set(obj, Double.parseDouble(o.toString()));
}

}

}
}

} catch (Exception ex) {
ex.printStackTrace();
// 如果还是读到的数据格式还是不对,只能放弃了
if (etimes > 7) {
throw ex;
}
etimes++;
if (o == null) {
readCellContent(key, fields, cell, obj, edf);
}
}
}

}
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
package com.fufu.config.excel;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.*;

/**
* 反射工具类.
*
* 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实类等工具函数.
*
* @author lwh
*/
public class ReflectionUtils {
private static final String SETTER_PREFIX = "set";

private static final String GETTER_PREFIX = "get";

private static final String CGLIB_CLASS_SEPARATOR = "$$";

private static Logger logger = LoggerFactory.getLogger(ReflectionUtils.class);

/**
* 调用Getter方法
* @param obj 对象
* @param propertyName 属性名称
* @return obj
*/
public static Object invokeGetter(Object obj, String propertyName) {
String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(propertyName);
return invokeMethod(obj, getterMethodName, new Class[] {}, new Object[] {});
}

/**
* 调用Setter方法, 仅匹配方法名
* @param obj 对象
* @param propertyName 属性名称
* @param value 新值
*/
public static void invokeSetter(Object obj, String propertyName, Object value) {
String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(propertyName);
invokeMethodByName(obj, setterMethodName, new Object[] { value });
}

/**
* 获取所有的成员变量,包括父类
*
* @param clazz
* @return 属性集合
* @throws Exception
*/
public static <T> Field[] getClassFieldsAndSuperClassFields(Class<T> clazz) throws Exception {

Field[] fields = clazz.getDeclaredFields();

if (clazz.getSuperclass() == null) {
throw new Exception(clazz.getName() + "没有父类");
}

Field[] superFields = clazz.getSuperclass().getDeclaredFields();

Field[] allFields = new Field[fields.length + superFields.length];

for (int i = 0; i < fields.length; i++) {
allFields[i] = fields[i];
}
for (int i = 0; i < superFields.length; i++) {
allFields[fields.length + i] = superFields[i];
}

return allFields;
}

/**
* 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数
* @param obj 对象
* @param fieldName 属性名称
* @return
*/
public static Object getFieldValue(final Object obj, final String fieldName) {
Field field = getAccessibleField(obj, fieldName);

if (field == null) {
throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]");
}

Object result = null;
try {
result = field.get(obj);
} catch (IllegalAccessException e) {
logger.error("不可能抛出的异常{}", e.getMessage());
}
return result;
}

/**
* 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数
* @param obj 对象
* @param fieldName 属性名称
* @param value 新值
*/
public static void setFieldValue(final Object obj, final String fieldName, final Object value) {
Field field = getAccessibleField(obj, fieldName);

if (field == null) {
throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]");
}

try {
field.set(obj, value);
} catch (IllegalAccessException e) {
logger.error("不可能抛出的异常:{}", e.getMessage());
}
}

/**
* 直接调用对象方法, 无视private/protected修饰符.
* 用于一次性调用的情况,否则应使用getAccessibleMethod()函数获得Method后反复调用.
* 同时匹配方法名+参数类型,
* @param obj 对象
* @param methodName 方法名称
* @param parameterTypes 参数类型
* @param args 参数
* @return obj
*/
public static Object invokeMethod(final Object obj, final String methodName, final Class<?>[] parameterTypes,
final Object[] args) {
Method method = getAccessibleMethod(obj, methodName, parameterTypes);
if (method == null) {
throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]");
}

try {
return method.invoke(obj, args);
} catch (Exception e) {
throw convertReflectionExceptionToUnchecked(e);
}
}

/**
* 直接调用对象方法, 无视private/protected修饰符,
* 用于一次性调用的情况,否则应使用getAccessibleMethodByName()函数获得Method后反复调用.
* 只匹配函数名,如果有多个同名函数调用第一个。
* @param obj 对象
* @param methodName 方法名称
* @param args 参数
* @return
*/
public static Object invokeMethodByName(final Object obj, final String methodName, final Object[] args) {
Method method = getAccessibleMethodByName(obj, methodName);
if (method == null) {
throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]");
}

try {
return method.invoke(obj, args);
} catch (Exception e) {
throw convertReflectionExceptionToUnchecked(e);
}
}

/**
* 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问.
*
* 如向上转型到Object仍无法找到, 返回null.
* @param obj 对象
* @param fieldName 属性名称
* @return 属性
*/
public static Field getAccessibleField(final Object obj, final String fieldName) {
Validate.notNull(obj, "object can't be null");
Validate.notBlank(fieldName, "fieldName can't be blank");
for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {
try {
Field field = superClass.getDeclaredField(fieldName);
makeAccessible(field);
return field;
} catch (NoSuchFieldException e) {// NOSONAR
// Field不在当前类定义,继续向上转型
}
}
return null;
}

/**
* 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问.
* 如向上转型到Object仍无法找到, 返回null.
* 匹配函数名+参数类型。
*
* 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)
* @param obj 对象
* @param methodName 方法名称
* @param parameterTypes 参数类型
* @return 方法
*/
public static Method getAccessibleMethod(final Object obj, final String methodName,
final Class<?>... parameterTypes) {
Validate.notNull(obj, "object can't be null");
Validate.notBlank(methodName, "methodName can't be blank");

for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) {
try {
Method method = searchType.getDeclaredMethod(methodName, parameterTypes);
makeAccessible(method);
return method;
} catch (NoSuchMethodException e) {
// Method不在当前类定义,继续向上转型
}
}
return null;
}

/**
* 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问.
* 如向上转型到Object仍无法找到, 返回null.
* 只匹配函数名。
*
* 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)
* @param obj 对象
* @param methodName 方法名称
* @return 方法
*/
public static Method getAccessibleMethodByName(final Object obj, final String methodName) {
Validate.notNull(obj, "object can't be null");
Validate.notBlank(methodName, "methodName can't be blank");

for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) {
Method[] methods = searchType.getDeclaredMethods();
for (Method method : methods) {
if (method.getName().equals(methodName)) {
makeAccessible(method);
return method;
}
}
}
return null;
}

/**
* 改变private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。
* @param method 对象方法
*/
public static void makeAccessible(Method method) {
if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers()))
&& !method.isAccessible()) {
method.setAccessible(true);
}
}

/**
* 改变private/protected的成员变量为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。
* @param field 对象属性
*/
public static void makeAccessible(Field field) {
if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) || Modifier
.isFinal(field.getModifiers())) && !field.isAccessible()) {
field.setAccessible(true);
}
}

/**
* 通过反射, 获得Class定义中声明的泛型参数的类型, 注意泛型必须定义在父类处
* 如无法找到, 返回Object.class.
* eg.
* public UserDao extends HibernateDao<User>
*
* @param clazz The class to introspect
* @return the first generic declaration, or Object.class if cannot be determined
*/
public static <T> Class<T> getClassGenricType(final Class clazz) {
return getClassGenricType(clazz, 0);
}

/**
* 通过反射, 获得Class定义中声明的父类的泛型参数的类型.
* 如无法找到, 返回Object.class.
*
* 如public UserDao extends HibernateDao<User,Long>
*
* @param clazz clazz The class to introspect
* @param index the Index of the generic ddeclaration,start from 0.
* @return the index generic declaration, or Object.class if cannot be determined
*/
public static Class getClassGenricType(final Class clazz, final int index) {

Type genType = clazz.getGenericSuperclass();

if (!(genType instanceof ParameterizedType)) {
logger.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType");
return Object.class;
}

Type[] params = ((ParameterizedType) genType).getActualTypeArguments();

if ((index >= params.length) || (index < 0)) {
logger.warn("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: "
+ params.length);
return Object.class;
}
if (!(params[index] instanceof Class)) {
logger.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter");
return Object.class;
}

return (Class) params[index];
}

/**
* 获取父类
* @param instance 对象实例
* @return 父类
*/
public static Class<?> getUserClass(Object instance) {
Class clazz = instance.getClass();
if ((clazz != null) && clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) {
Class<?> superClass = clazz.getSuperclass();
if ((superClass != null) && !Object.class.equals(superClass)) {
return superClass;
}
}
return clazz;

}

/**
* 将反射时的checked exception转换为unchecked exception
* @param e exception
* @return unchecked exception
*/
public static RuntimeException convertReflectionExceptionToUnchecked(Exception e) {
if ((e instanceof IllegalAccessException) || (e instanceof IllegalArgumentException)
|| (e instanceof NoSuchMethodException)) {
return new IllegalArgumentException(e);
} else if (e instanceof InvocationTargetException) {
return new RuntimeException(((InvocationTargetException) e).getTargetException());
} else if (e instanceof RuntimeException) {
return (RuntimeException) e;
}
return new RuntimeException("Unexpected Checked Exception.", e);
}
}

Controller

1
2
3
4
5
6
7
8
9
10
11
12
@PostMapping(value = "/excelUpload")
@ResponseBody
public String uploadExcel(@RequestParam("file") MultipartFile file) throws Exception {
if(file==null || file.isEmpty()){
return JsonUtil.getInstance().putData("ret", -1).putData("msg", "上传文件不能为空!").pushData();
}
try{
return restfulService.uploadSatelliteExcel(file);
}catch(Exception e){
return JsonUtil.getInstance().putData("ret", -1).putData("msg", e.getMessage()).pushData();
}
}

Service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* 上传卫星excel文件
*/
public String uploadSatelliteExcel(MultipartFile excelFile){
ExcelDataFormatter edf = new ExcelDataFormatter();
InputStream is = null;
try {
is = excelFile.getInputStream();

List<Satellite> list = ExcelToBean.readFromFile(edf,is, Satellite.class);
satelliteMapper.deleteAll();
for(Satellite satellite : list){
satelliteMapper.insert(satellite);
}
} catch (Exception e) {
e.printStackTrace();
return JsonUtil.getInstance().putData("ret", -1).putData("msg", e.getMessage()).pushData();
}
return JsonUtil.getInstance().putData("ret", 1).putData("msg", "上传成功!").pushData();
}

Entity

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
package com.fufu.entity;

import com.fufu.config.excel.Excel;

import java.util.Date;

public class Satellite implements java.io.Serializable{
private Long id;
@Excel(name = "卫星名称")
private String satelliteName;
@Excel(name = "编号")
private String satelliteNo;
@Excel(name = "国别")
private String country;
@Excel(name = "类别")
private Integer satelliteType;
@Excel(name = "时间段开始")
private Date startTime;
@Excel(name = "时间段结束")
private Date endTime;
@Excel(name = "安全时长")
private Integer safeTime;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getSatelliteName() {
return satelliteName;
}
public void setSatelliteName(String satelliteName) {
this.satelliteName = satelliteName;
}

public String getSatelliteNo() {
return satelliteNo;
}
public void setSatelliteNo(String satelliteNo) {
this.satelliteNo = satelliteNo;
}

public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}

public Integer getSatelliteType() {
return satelliteType;
}
public void setSatelliteType(Integer satelliteType) {
this.satelliteType = satelliteType;
}

public Date getStartTime() {
return startTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}

public Date getEndTime() {
return endTime;
}
public void setEndTime(Date endTime) {
this.endTime = endTime;
}

public Integer getSafeTime() {
return safeTime;
}
public void setSafeTime(Integer safeTime) {
this.safeTime = safeTime;
}

}

这里的注解对应Excel的第一行,如图

"图片描述"

源码:https://github.com/qq1028951741/springbootdemo or 右上角github进去,springbootdemo项目,如果对您有帮助,麻烦点下star,谢谢


人生两苦:想要却不得,拥有却失去。 –褚禄山
珍惜当下,与君共勉~


本文标题:SpringBoot:Excel文件解析

文章作者:fufua

发布时间:2018年11月27日 - 11:18:13

最后更新:2018年11月27日 - 14:11:25

原始链接:https://qq1028951741.github.io/2018/11/27/SpringBoot:Excel文件解析/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

this is end, thank you for reading