1.导入excel:MultipartFile file 分析成指定对象list
2. 关于POI读取excel中数字,丢失精度,如:表格数值11.2 ,解析出来是11.19999999...
第一步:
///前端传输file... MultipartFile file = new MultipartFile(); // 先验证上传的数据 String originalFilename = file.getOriginalFilename(); if (originalFilename == null) { //校验"文件不能为空" } if (!(originalFilename.endsWith(".xls") || originalFilename.endsWith(".xlsx"))) { ///验证格式:"请选择xls文件上传" } //工具对象传输 自定义的 dto 字段与excel对应 ExcelUtil<ExcelDto> accessReqExcelUtil = new ExcelUtil<>(ExcelDto.class); List<ExcelDto> accessList = Lists.newArrayList(); try { //调用方法返回list,也可以自定义方法名称,传参 accessList = accessReqExcelUtil.importExcel(file); } catch (Exception e) { e.printStackTrace(); } //后续逻辑...
第二步:调用工具类:
/** * Excel工具类 * */ public class ExcelUtil<T> { public Class<T> clazz; public ExcelUtil(Class<T> clazz) { this.clazz = clazz; } /** * 读取Excel内容转为List */ public List<T> importExcel(MultipartFile file) throws Exception{ return importExcel(StringUtils.EMPTY, file); } /** * 读取Excel内容转为List */ public List<T> importExcel(String sheetName, MultipartFile file) throws Exception { U.assertException(U.isBlank(file),"上传的文件为空"); //获取文件名 String fileName = file.getOriginalFilename(); U.assertException(!(fileName.endsWith(".xls") || fileName.endsWith(".xlsx")), "请选择Excel文件上传"); // List<T> list = new ArrayList<>(); Workbook workbook = WorkbookFactory.create(file.getInputStream()); Sheet sheet; if (StringUtils.isNotEmpty(sheetName)){ // 如果指定sheet名,则取指定sheet中的内容. sheet = workbook.getSheet(sheetName); } else { // 如果传入的sheet如果名字不存在,默认指向第一个sheet. sheet = workbook.getSheetAt(0); } if (sheet == null) throw new IOException("文件sheet不存在"); //获取数据 int rows = sheet.getLastRowNum(); if(rows==0) U.assertException("目前的工作簿没有数据"); //行号从0开始,所以需要 1 rows = rows 1; // 默认序号 int serialNum = 0; // 只有在有数据的时候才能处理 得到类的一切field. Field[] allFields = clazz.getDeclaredFields(); ///用于验证是否存在某些字段 Map<String,Field> fieldNameMap = new HashMap<>(); // 定义一个map用于存储列的序号和field. Map<Integer,Field> fieldsMap = new HashMap<>(); for (Field field : allFields) { // 可访问设置类的私有字段属性. field.setAccessible(true); fieldsMap.put( serialNum, field); fieldNameMap.put(field.getName(),field); } // DateTimeFormatter dtf = DateTimeFormatter.ofPattern(DateFormatType.YYYY_MM_DD_HH_MM_SS.getValue()); DateTimeFormatter df = DateTimeFormatter.ofPattern(DateFormatType.YYYY_MM_DD.getValue()); SimpleDateFormat sdf = new SimpleDateFormat(DateFormatType.YYYY_MM_DD_HH_MM_SS.getValue()); // Row row = null; Cell cell = null; try{ // 从第二行开始,默认第一行是表头. for (int i = 1; i < rows; i ) { row = sheet.getRow(i); if (row==null) continue; T entity = clazz.newInstance(); for (int j = 0; j < serialNum; j ) { cell = row.getCell(j); if (cell == null) continue; // 从map对应列获得field. Field field = fieldsMap.get(j 1); // 取得类型,并根据对象类型设置值. Class<?> fieldType = field.getType(); String c; //excel如果是数字类型,转化 if (cell.getCellTypeEnum().equals(CellType.NUMERIC) && fieldType != Date.class) { NumberFormat numberFormat = NumberFormat.getNumberInstance(); double d = cell.getNumericCellValue(); // 关键在这里! c = numberFormat.format(d); } else { // 先设置Cell的类型,然后你可以用纯数字作为纯数字String读入类型(这里的数字类型) c精度问题可能存在) cell.setCellType(CellType.STRING); c = cell.getStringCellValue(); } if (StringUtils.isEmpty(c)) continue; if (String.class == fieldType) { field.set(entity, c); } else if ((Integer.TYPE == fieldType) || (Integer.class == fieldType)) { field.set(entity, Integer.parseInt(c)); } else if ((Long.TYPE == fieldType) || (Long.class == fieldType)) { field.set(entity, Long.valueOf(c)); } else if ((Float.TYPE == fieldType) || (Float.cass == fieldType)) {
field.set(entity, Float.valueOf(c));
}else if ((Short.TYPE == fieldType) || (Short.class == fieldType)) {
field.set(entity, Short.valueOf(c));
} else if ((Double.TYPE == fieldType) || (Double.class == fieldType)) {
field.set(entity, Double.valueOf(c));
} else if (Character.TYPE == fieldType) {
if (c.length() > 0) {
field.set(entity, c.charAt(0));
}
} else if (Date.class == fieldType) {
if (cell.getCellTypeEnum() == CellType.NUMERIC) {
cell.setCellValue(sdf.format(cell.getNumericCellValue()));
c = sdf.format(cell.getNumericCellValue());
} else {
c = cell.getStringCellValue();
}
} else if (java.math.BigDecimal.class == fieldType) {
try{
field.set(entity, NumberUtil.toBigDecimal(c));
}catch (Exception ex){
U.assertException("数值类型转换失败,请检查单元格值是否符合规范");
}
} else if (LocalDateTime.class == fieldType) {
field.set(entity, LocalDateTime.parse(excelDoubleToDate(c, DateFormatType.YYYY_MM_DD_HH_MM_SS),dtf));
}else if (LocalDate.class == fieldType) {
field.set(entity, LocalDate.parse(excelDoubleToDate(c,DateFormatType.YYYY_MM_DD),df));
}
}
if (BeanUtil.isNotEmpty(entity)) {
//判断是否有行号字段,有的话赋值
if (fieldNameMap.containsKey("rowNum")){
//记录一下行数
fieldNameMap.get("rowNum").set(entity,row.getRowNum()+1);
}
list.add(entity);
}
}
}catch (Exception ex){
ex.printStackTrace();
U.assertException(StrUtil.format("解析第{}行,第{}列时出错,错误原因:{}",
row==null?"null":row.getRowNum()+1,
cell==null?"null":cell.getColumnIndex()+1,
ex.getMessage()));
}
return list;
}
//解析Excel日期格式
public static String excelDoubleToDate(String strDate,DateFormatType dateFormatType) {
try {
SimpleDateFormat sdf = new SimpleDateFormat(dateFormatType.getValue());
Date tDate = doubleToDate(Double.parseDouble(strDate));
return sdf.format(tDate);
}catch (Exception e){
//e.printStackTrace();
return strDate;
}
}
}