资讯详情

POI excel导入解析成list;(解决数字精度问题)

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;
        }
    }
}

标签: 继电器底座dtf08a

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台