利用反射和泛型,传入要封装的bean和file,转换成对于的list集合
//用于判断excel版本
private final static String EXCEL2003L = ".xls"; //2003- 版本的excel
private final static String EXCEL2007U = ".xlsx"; //2007+ 版本的excel
/***
* 通用的Excel导入方法
*
* @param file 传入需要导入的file
* @param tclass 实体Class
* @param <T> 返回实体信息集合
* @return
* @throws IOException
*/
public static <T> List<T> importBaseExcel(MultipartFile file, Class<T> tclass) throws IOException {
Workbook workbook = null;
try {
//选择合适的文本类型
workbook = chooseWorkbook(file);
//获取工作表
Sheet sheet = workbook.getSheetAt(0);
//获取sheet中第一行行号
int firstRowNum = sheet.getFirstRowNum();
//获取sheet中最后一行行号
int lastRowNum = sheet.getLastRowNum();
//获取该实体所有定义的属性 返回Field数组
Field[] field = tclass.getDeclaredFields();
List<T> list = new LinkedList();
/**
* line = 1 :从表的第二行开始获取记录
*/
if (null != sheet) {
//为日期转换限定格式
//循环插入数据
for (int i = firstRowNum + 1; i <= lastRowNum; i++) {
Row row = sheet.getRow(i);
//如果为空,跳过读取下一行
if (null == row) {
continue;
}
//根据反射获取Java对象
T entity = tclass.newInstance();
//除自增编号外,实体字段匹配sheet列
for (int j = 0; j < field.length; j++) {
//获取属性的名字, 将属性的首字符大写,方便构造set方法
String name = "set" + field[j].getName().substring(0, 1).toUpperCase().concat(field[j].getName().substring(1));
//获取属性的类型
String type = field[j].getGenericType().toString();
//getMethod只能调用public声明的方法,而getDeclaredMethod基本可以调用任何类型声明的方法
Method method = entity.getClass().getDeclaredMethod(name, field[j].getType());
Cell cell = row.getCell(j);
//根据属性类型装入值
switch (type) {
case "char":
case "java.lang.Character":
case "class java.lang.String":
method.invoke(entity, getCellValue(cell));
break;
case "int":
case "class java.lang.Integer":
method.invoke(entity, Integer.valueOf(getCellValue(cell)));
break;
case "class java.util.Date":
method.invoke(entity, cell.getDateCellValue());
break;
case "double":
case "class java.lang.Double":
method.invoke(entity, Double.valueOf(getCellValue(cell)));
break;
case "float":
case "class java.lang.Float":
method.invoke(entity, Float.valueOf(getCellValue(cell)));
break;
case "long":
case "class java.lang.Long":
method.invoke(entity, Long.valueOf(getCellValue(cell)));
break;
case "short":
case "class java.lang.Short":
method.invoke(entity, Short.valueOf(getCellValue(cell)));
break;
case "class java.math.BigDecimal":
method.invoke(entity, new BigDecimal(Double.valueOf(getCellValue(cell))));
break;
default:
break;
}
}
//添加到list集合中
list.add(entity);
}
return list;
} else {
//没有内容
return null;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
workbook.close();
}
return null;
}
/**
* 通用的Excel导出方法
*
* @param excelName Excel表名
* @param titles Excel的表头内容
* @param infoList Excel的表体内容
* @param httpServletResponse 用于响应客户端的response
* @throws IllegalAccessException
* @throws NoSuchMethodException
* @throws InvocationTargetException
*/
public static void exportBaseExcel(String excelName, String[] titles, List infoList, HttpServletResponse httpServletResponse) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
//首先,将list集合转换为数组
List<Object[]> values = beanToArraysUtil(infoList);
// 第一步,创建一个webbook,对应一个Excel文件
HSSFWorkbook wb = new HSSFWorkbook();
// 第二步,在webbook中添加一个sheet,对应Excel文件中的sheet
HSSFSheet sheet = wb.createSheet("会议签到表");
// 第三步,在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制short
HSSFRow row = sheet.createRow((int) 0);
// 第四步,创建单元格,并设置值表头 设置表头居中
HSSFCellStyle style = wb.createCellStyle();
style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 创建一个居中格式
//第五步,创建标题
for (int i = 0; i < titles.length; i++) {
HSSFCell cell = row.createCell((short) i);
cell.setCellValue(titles[i]);
}
//第六步,写入实体数据,遍历创建内容
for (int i = 0; i < values.size(); i++) {//总共多少行
Object[] str = values.get(i);
row = sheet.createRow(i + 1);//第几行
for (int j = 0; j < str.length; j++) {
//将内容按顺序赋给对应的列对象
row.createCell(j).setCellValue(str[j].toString());//每行塞什么数据
}
}
//第六步,下载excel表格
OutputStream out = null;
try {
out = httpServletResponse.getOutputStream();
String fileName = excelName + ".xls";// 文件名
httpServletResponse.setContentType("application/x-msdownload");//文件格式
httpServletResponse.setHeader("Content-Disposition", "attachment; filename="
+ URLEncoder.encode(fileName, "UTF-8"));//响应头以及文件名,编码格式
wb.write(out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 功能分析:根据文件选择excel版本
*
* @return
* @throws Exception
*/
private static Workbook chooseWorkbook(MultipartFile file) throws Exception {
Workbook workbook = null;
InputStream ins = file.getInputStream();
String filename = file.getOriginalFilename();
String fileType = (filename.substring(filename.lastIndexOf("."), filename.length())).toLowerCase();
if (EXCEL2003L.equals(fileType)) {
workbook = new HSSFWorkbook(ins); //2003-
} else if (EXCEL2007U.equals(fileType)) {
workbook = new XSSFWorkbook(ins); //2007+
} else {
throw new Exception("解析的文件格式有误!");
}
return workbook;
}
/***
* 功能分析:根据类型获取对应的值
*
* @param cell 对应的表单元
* @return
*/
public static String getCellValue(Cell cell) {
String cellValue = "";
if (cell == null) {
return cellValue;
}
// 判断数据的类型
switch (cell.getCellType()) {
case Cell.CELL_TYPE_NUMERIC: // 数字
//short s = cell.getCellStyle().getDataFormat();
if (HSSFDateUtil.isCellDateFormatted(cell)) {// 处理日期格式、时间格式
SimpleDateFormat sdf = null;
// 验证short值
if (cell.getCellStyle().getDataFormat() == 14) {
sdf = new SimpleDateFormat("yyyy/MM/dd");
} else if (cell.getCellStyle().getDataFormat() == 21) {
sdf = new SimpleDateFormat("HH:mm:ss");
} else if (cell.getCellStyle().getDataFormat() == 22) {
sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
} else {
// throw new RuntimeException("日期格式错误!!!");
sdf = new SimpleDateFormat("yyyy-MM-dd:HH:mm:ss");
}
Date date = cell.getDateCellValue();
cellValue = sdf.format(date);
} else if (cell.getCellStyle().getDataFormat() == 0) {//处理数值格式
cell.setCellType(Cell.CELL_TYPE_STRING);
cellValue = String.valueOf(cell.getRichStringCellValue().getString());
}
break;
case Cell.CELL_TYPE_STRING: // 字符串
cellValue = String.valueOf(cell.getStringCellValue());
break;
case Cell.CELL_TYPE_BOOLEAN: // Boolean
cellValue = String.valueOf(cell.getBooleanCellValue());
break;
case Cell.CELL_TYPE_FORMULA: // 公式
cellValue = String.valueOf(cell.getCellFormula());
break;
case Cell.CELL_TYPE_BLANK: // 空值
cellValue = null;
break;
case Cell.CELL_TYPE_ERROR: // 故障
cellValue = "非法字符";
break;
default:
cellValue = "未知类型";
break;
}
return cellValue;
}
/**
* 功能分析:把对象集合转换成数组集合
*
* @param list:需要操作的实体类集合
* @return
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws IllegalAccessException
*/
private static List<Object[]> beanToArraysUtil(List list) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
//设置用到的变量参数
String name = null, type = null, m_name = null;
Object value = null;
//创建一个二维字符串数组存放数据
List<Object[]> list1 = new ArrayList<>();
//获取实体类方法操作对象
Method m = null;
//判断要提取实体类属性数据的集合是否为空
if (list != null) {
//遍历集合中的实体类
for (int y = 0; y < list.size(); y++) {
//获取每一个实体类
Object object = list.get(y);
//获取实体类的所有属性,返回Field数组
Field[] fields = object.getClass().getDeclaredFields();
//创建一个数组存放实体类属性数据
Object[] str = new Object[fields.length];
//遍历实体类的所有属性
for (int i = 0; i < fields.length; i++) {
name = fields[i].getName();//获取属性的名字
m_name = name.substring(0, 1).toUpperCase() + name.substring(1); //将属性的首字符大写,方便构造get,set方法
type = fields[i].getGenericType().toString(); //获取属性的类型
//判断属性的类型修改数据结构
switch (type) {
case "class java.lang.String":
m = object.getClass().getMethod("get" + m_name); //组装getter方法
value = (String) m.invoke(object); //调用getter方法获取属性值
if (value != null) {
/**
* 你可以进行附加操作
*/
}
break;
case "class java.lang.Double":
m = object.getClass().getMethod("get" + m_name);
value = m.invoke(object); //调用getter方法获取属性值
if (value != null) {
}
break;
case "class java.lang.Boolean":
m = object.getClass().getMethod("get" + m_name); //组装getter方法
value = m.invoke(object); //调用getter方法获取属性值
if (value != null) {
}
break;
case "class java.lang.Integer":
m = object.getClass().getMethod("get" + m_name);
value = m.invoke(object); //调用getter方法获取属性值
if (value != null) {
}
break;
case "class java.util.Date":
m = object.getClass().getMethod("get" + m_name);
value = m.invoke(object); //调用getter方法获取属性值
if (value != null) {
value = new SimpleDateFormat("yyyy-MM-dd").format(value);//改变时间的格式
}
break;
case "class java.lang.Float":
m = object.getClass().getMethod("get" + m_name);
value = m.invoke(object); //调用getter方法获取属性值
if (value != null) {
}
break;
case "class java.lang.Long":
m = object.getClass().getMethod("get" + m_name);
value = m.invoke(object); //调用getter方法获取属性值
if (value != null) {
}
break;
case "class java.lang.Byte":
m = object.getClass().getMethod("get" + m_name);
value = m.invoke(object); //调用getter方法获取属性值
if (value != null) {
}
break;
}
//把实体类中的属性存放到一个字符串数组中
str[i] = value;
}
//把字符串数组存放到集合中
list1.add(str);
}
}
return list1;
}
多谢下面这位大佬的帮助
参考: https://blog.csdn.net/qq_40162735/article/details/84874862