一、流程概念
我们需要把excel通过上传得方式导入数据库,需要以下几个步骤
* 将excel上传到服务器指定文件内并重命名(upload)
* 获取到文件公共路径和别名路径
* 将上传得文件转化成输入流(poi框架)
* 通过方法,将输入流文件数值转化成List<List<Object>>对象
* 遍历excel中得值,调用一次setFieldValueByFieldName方法,就对属性赋值一次,每次循环拿到一条数据,最终得到整个数据。
* 后台调用getObjectList(file, Exam.class)。
二、conroller中的方法
@PostMapping("/upload") public ResultJson uploadFile(MultipartFile file )
throws Exception { List<Object> objects = ObjectList.getObjectList(file,
Exam.class); List<Exam> list = (List) objects; boolean flag =
examService.saveOrUpdateBatch(list); if (flag) { return ResultJson.ok(); }
return ResultJson.failure(ResultCode.NOT_UPDATE); }
前天传过来得是二进制文件MultipartFile file
调用getObjectList方法(二进制文件,实体类对象)
package tech.niua.common.excelimport; public class ObjectList { /** *
封装的将Excel文件信息转换成List<Object>的方法,需要传实体类 * @param file * @param * @return *
@throws Exception */ public static List<Object> getObjectList(MultipartFile
file, Class cls) throws Exception { //获取到了文件根路径 String filePath =
NiuaConfig.getUploadPath(); // 上传并返回文件除根路径得路径
052d1c92-fc6a-4e15-a7c9-7d193c1a4bec.xlsx String fileName =
FileUploadUtils.upload(filePath, file); //完整的上传文件的路径 fileName =filePath+
File.separator+fileName; //把上传的文件转换成输入流(因为我们使用得是poi框架,要求使用输入流) FileInputStream
fileInputStream = new FileInputStream(new File(fileName)); //输入流 和 文件路径 作为参数传入
获取List<List<Object>>类型数据的方法中 List<List<Object>> list =
ExcelUtils.getListByExcel(fileInputStream,fileName); /** *
将数据转换成List<Object>类型的数据 */ //初始化标题 List<Object> firstRows = null;
//如果转换过来的数据不为空,拿到标题,在之前的方法中判断过是否为空 if (list != null && list.size() > 0) {
firstRows = list.get(0); } //初始化实际数据 初始化对象 List<Object> excelDate = new
ArrayList<>(); //从一开始遍历,为的是拿到数据 for (int i = 1; i < list.size(); i++) {
//每一行实例化一个List<Object>数据,后面插入的也是这些 List<Object> rows = list.get(i);
//实例化对象,方便赋值(for里面是每次都改变数据,防止都访问这一个地址) Object obj = cls.newInstance();
//对obj的每一个的字段进行赋值 for (int j = 0; j < rows.size(); j++) {
//把excel转过来的数据的每个字段的值转换成String类型 String cellVal = (String) rows.get(j);
//对obj进行赋值(对象,字段名,字段值) ObjectList.setFieldValueByFieldName(obj,
firstRows.get(j).toString().trim(), cellVal); } //添加进List<Object>,每个obj都是一条数据
excelDate.add(obj); } return excelDate; } public static void
setFieldValueByFieldName(Object object, String fieldName, Object val) { try {
//反射拿到实体类每个变量得对象 Field[] fields = object.getClass().getDeclaredFields();
//把实体类每个变量遍历一遍 for (int i = 0; i < fields.length; i++) { //拿到一个对象 Field field =
fields[i]; ///可以访问私有 field.setAccessible(true); //判断excel注解修饰 Excel excel =
field.getAnnotation(Excel.class); if(excel== null){ continue; }
//如果excel转化过来的标题名和实体类字段或者实体类注解相同,说明对应上了,赋值!!
if(fieldName.equals(excel.name())||fieldName.equals(field.getName())){
//将excel中得String类型得数值,转化成对应实体类属性,把属性值set进对象 if(field.getType()==
Integer.class){ //把有这个类型的要被赋值的对象和这个类型的数值当作参数,可以赋值
field.set(object,Integer.valueOf(val.toString())); } else if(field.getType()==
Long.class){ field.set(object,Long.valueOf(val.toString())); }else
if(field.getType()== LocalDateTime.class){ DateTimeFormatter df =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); LocalDateTime time =
LocalDateTime.parse(val.toString(), df); field.set(object,time); } else{
field.set(object, val); } } } } catch (Exception e) { e.printStackTrace(); } } }
package tech.niua.common.excelimport; /** * Created by ws * Date :2022/4/29 *
Description : excel导入工具类 * Version :1.0 */ public class ExcelUtils { private
final static String excel2003L =".xls"; //2003- 版本的excel private final static
String excel2007U =".xlsx"; //2007+ 版本的excel /** *
@Description:获取IO流中的数据,组装成List<List<Object>>对象 * @param in,fileName * @return *
@throws IOException */ public static List<List<Object>>
getListByExcel(InputStream in, String fileName) throws Exception{
List<List<Object>> list = null; //创建Excel工作薄 Workbook work =
getWorkbook(in,fileName); if(null == work){ throw new
Exception("创建Excel工作薄为空!"); } Sheet sheet = null; //页数 Row row = null; //行数
Cell cell = null; //列数 list = new ArrayList<List<Object>>(); //遍历Excel中所有的sheet
for (int i = 0; i < work.getNumberOfSheets(); i++) { //取某个sheet sheet =
work.getSheetAt(i); if(sheet== null){continue;} //遍历当前sheet中的所有行 for (int j =
sheet.getFirstRowNum(); j <= sheet.getLastRowNum(); j++) { row =
sheet.getRow(j); if(row == null){continue;} //遍历所有的列 List<Object> li = new
ArrayList<Object>(); for (int y = row.getFirstCellNum(); y <
row.getLastCellNum(); y++) { cell = row.getCell(y); li.add(getValue(cell)); }
list.add(li); } } return list; } /** * @Description:根据文件后缀,自适应上传文件的版本 * @param
inStr,fileName * @return * @throws Exception */ public static Workbook
getWorkbook(InputStream inStr, String fileName) throws Exception{ Workbook wb =
null; String fileType = fileName.substring(fileName.lastIndexOf("."));
if(excel2003L.equals(fileType)){ wb = new HSSFWorkbook(inStr); //2003- }else
if(excel2007U.equals(fileType)){ wb = new XSSFWorkbook(inStr); //2007+ }else{
throw new Exception("解析的文件格式有误!"); } return wb; } /** *
@Description:对表格中数值进行格式化 * @param cell * @return */ //解决excel类型问题,获得数值 public
static String getValue(Cell cell) { String value = ""; if(null == cell){ return
value; } switch (cell.getCellType()) { //数值型 case NUMERIC: if
(DateUtil.isCellDateFormatted(cell)) { //如果是date类型则 ,获取该cell的date值 Date date =
DateUtil.getJavaDate(cell.getNumericCellValue()); SimpleDateFormat format = new
SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); value = format.format(date);; }else
{// 纯数字 BigDecimal big= new BigDecimal(cell.getNumericCellValue()); value =
big.toString(); //解决1234.0 去掉后面的.0 if(null!= value&&!"".equals(value.trim())){
String[] item = value.split("[.]"); if(1<item.length&&"0".equals(item[1])){
value = item[0]; } } } break; //字符串类型 case STRING: value =
cell.getStringCellValue(); break; // 公式类型 case FORMULA: //读公式计算值 value =
String.valueOf(cell.getNumericCellValue()); if (value.equals("NaN")) {//
如果获取的数据值为非法值,则转换为获取字符串 value = cell.getStringCellValue(); } break; // 布尔类型 case
BOOLEAN: value = " "+ cell.getBooleanCellValue(); break; default: value =
cell.getStringCellValue(); } if("null".endsWith(value.trim())){ value= ""; }
return value; } }
三、导入成功