Springboot中poi导入导出Excel的使用

  1. 标题
    日常开发中Excel文件的导入导出已经是很基本的需求,该文章用于记录在项目实战中使用poi的相关情况,用于后期巩固

  2. 实现
    1.Maven导入相关Jar包

      <dependency>
             <groupId>com.xtoneict</groupId>
             <artifactId>xtoneict-dcp-common</artifactId>
             <version>4.1.0</version>
         </dependency>
    

    2.工具类

     public class ExcelUtils {
     /**
      *  解析普通二维表单
      * @param in  文件输入流
      * @param fileName 文件名称
      * @param tableType  表单类型
      * @param tableId  表单ID
      * @param fieldNames 表头名称集合
      * @param types  表头字段所属类型
      * @return
      */
     public static  List<BaseTableInfo> getBankListByExcel(InputStream in, String fileName, TableType tableType,String tableId,
                                                          Map<Integer,String> fieldNames,List<String> types){
         try {
             List<BaseTableInfo> list = new ArrayList<>();
             Sheet sheet = getSheet(in, fileName);
             Row row = null;
             Cell cell = null;
             BaseTableInfo baseTableInfo = null;
             //根据表单类型   获取表格起始行行号
             int firstRowNum = 0;
             // 根据表单类型  获取表格结束列号
             int lastCellNum = 0;
             switch (tableType){
                 case T_RISK:
                     firstRowNum = 3;
                     lastCellNum = 13;
                     break;
                 case T_SECTOR:
                     firstRowNum = 2;
                     lastCellNum = 6;
                     break;
                 case T_DEBT:
                     firstRowNum = 4;
                     lastCellNum = 31;
                     break;
                 default:
                     break;
             }
             //根据不同Excel表格 获取读取开始单元格
             for (int j = firstRowNum; j <= sheet.getLastRowNum(); j++) {
                 //读取一行
                 row = sheet.getRow(j);
                 //去掉空行和表头
                 if(row==null || row.getFirstCellNum()==j){continue;}
                 baseTableInfo = getTableInfoEntity(tableType, tableId, baseTableInfo);
                 boolean flag = false;
                 //遍历所有的列
                 for (int y = row.getFirstCellNum(); y < lastCellNum; y++) {
                     cell = row.getCell(y);
                     Object cellValue = getCellValue(cell);
                     if(cellValue != null){
                         flag = true;
                     }
                     cellValueType(cellValue,fieldNames.get(y),baseTableInfo,types.get(y));
                 }
                 if(!flag){continue;}
                 list.add(baseTableInfo);
             }
             in.close();
             return list;
         } catch (StandardException e) {
             log.debug("export excel for {}",e.getMessage());
             throw new StandardException(e.getMessage());
         }catch (Exception e) {
             log.debug("export excel for {}",e.getMessage());
             throw new StandardException("表格类型不匹配,请选择正确的表格模板");
         }
     }
    
     /**
      * 根据当前类型获取 实体对象    用于反射生成对象
      * @param tableType
      * @param tableId
      * @param baseTableInfo
      * @return
      */
     private static BaseTableInfo getTableInfoEntity(TableType tableType, String tableId, BaseTableInfo baseTableInfo) {
         if(tableType.equals(TableType.T_RISK)){
             baseTableInfo = RiskInfoEntity.builder().id(UUIDUtils.newUUID().toString()).tableId(tableId).tableType(tableType).build();
         }
         if(tableType.equals(TableType.T_SECTOR)){
             baseTableInfo = SectorInfoEntity.builder().id(UUIDUtils.newUUID().toString()).tableId(tableId).tableType(tableType).build();
         }
         if(tableType.equals(TableType.T_DEBT)){
             baseTableInfo = DebtInfoEntity.builder().id(UUIDUtils.newUUID().toString()).tableId(tableId).tableType(tableType).build();
         }
         return baseTableInfo;
     }
    
     /**
      * 反射赋值给字段
      * @param cellValue  单元格值
      * @param fieldName  文件名称
      * @param baseTableInfo  反射对象实体类
      * @param type  字段类型   
      */
     private static void cellValueType(Object cellValue, String fieldName, BaseTableInfo baseTableInfo,String type){
         if(cellValue != null){
             switch (type){
                 case "String":
                     cellValue = cellValue.toString();
                     break;
                 case "Integer":
                     Double parseDouble = Double.parseDouble(cellValue.toString());
                     cellValue = Integer.valueOf(parseDouble.intValue());
                     break;
                 case "Date":
                     Date startTime = new GregorianCalendar(1900, 0, -1).getTime();
                     Double dateDouble = Double.parseDouble(cellValue.toString());
                     Date date = DateUtils.addDays(startTime,Integer.valueOf(dateDouble.intValue()));
                     cellValue = date;
                     break;
                 case "BigDecimal":
                     if("".equals(cellValue.toString())){
                         cellValue = new BigDecimal("0");
                     }else{
                         BigDecimal bigDecimal = new BigDecimal(cellValue.toString());
                         // 设置最多保留4位  四舍五入
                         bigDecimal = bigDecimal.setScale(4,BigDecimal.ROUND_HALF_UP);
                         cellValue = bigDecimal;
                     }
                     break;
                 default:
                     break;
             }
             try {
                 Field declaredField = baseTableInfo.getClass().getDeclaredField(fieldName);
                 declaredField.setAccessible(true);
                 declaredField.set(baseTableInfo,cellValue);
                 declaredField.setAccessible(false);
             }catch (Exception e){
                 throw new StandardException("反射设置属性值出现错误");
             }
         }
     }
    
     /**
      * 解析一行表头两列数据   读取两行生成一个实体对象
      * @param in
      * @param fileName
      * @param tableId
      * @param moneyIndexs
      * @param moneyTypes
      * @param numIndexs
      * @param numTypes
      * @return
      * @throws Exception
      */
     public static  List<MoneyInfoEntity> getMoneyInfoByExcel(InputStream in, String fileName, String tableId,TableType tableType,
                    Map<Integer, String> moneyIndexs, List<String> moneyTypes, Map<Integer, String> numIndexs, List<String> numTypes) {
         try {
             List<MoneyInfoEntity> list = new ArrayList<>();
             Sheet sheet = getSheet(in, fileName);
             int firstRowNum = 2;
             // 根据表单类型  获取表格结束列号
             int lastCellNum = 9;
             MoneyInfoEntity entity =  MoneyInfoEntity.builder().id(UUIDUtils.newUUID().toString()).tableId(tableId).tableType(tableType).build();
             for (int i = firstRowNum; i <= sheet.getLastRowNum(); i++) {
                 Row row = sheet.getRow(i);
                 if(i % 2 == 1){
                     for (int j = row.getFirstCellNum(); j < lastCellNum; j++) {
                         Cell cell = row.getCell(j);
                         Object cellValue = getCellValue(cell);
                         cellValueType(cellValue,moneyIndexs.get(j),entity,moneyTypes.get(j));
                     }
                     // 读取两行表格后 重新创建对象
                     list.add(entity);
                     entity = MoneyInfoEntity.builder().id(UUIDUtils.newUUID().toString()).tableId(tableId).tableType(tableType).build();
                 }else{
                     for (int j = row.getFirstCellNum(); j < lastCellNum; j++) {
                         Cell cell = row.getCell(j);
                         Object cellValue = getCellValue(cell);
                         cellValueType(cellValue,numIndexs.get(j),entity,numTypes.get(j));
                     }
                 }
             }
             return  list;
         }catch (StandardException e) {
             log.debug("export excel for {}",e.getMessage());
             throw new StandardException(e.getMessage());
         }catch (Exception e) {
             log.debug("export excel for {}",e.getMessage());
             throw new StandardException("表格类型不匹配,请选择正确的表格模板");
         }
     }
     /**
      * 获取解析表格
      * @param in
      * @param fileName
      * @return
      * @throws Exception
      */
     private static Sheet getSheet(InputStream in, String fileName) throws IOException {
         //创建Excel工作薄
         Workbook work = WorkbookFactory.create(in);
         if (null == work) {
             throw new StandardException("创建Excel工作薄为空!");
         }
         if (work.getNumberOfSheets() > 1) {
             throw new StandardException("当前导入Excel中存在多个表格,请检查Excel文件");
         }
         Sheet sheet = work.getSheetAt(0);
         if (sheet == null) {
             throw new StandardException("请检查Excel文件是否存在表格");
         }
         return sheet;
     }
    
    
     /**
      * 解析复杂Excel表格   适用于每个单元格对应一个固定值
      * @param in
      * @param fileName
      * @param entities      数据库加载出来表格对应单元格值
      * @return
      * @throws Exception
      */
     public static Map<String, Object> getBankListByExcelAndOpeartion(InputStream in, String fileName,List<TableInfoEntity> entities){
         //创建Excel工作薄
         try {
             Sheet sheet = getSheet(in, fileName);
             Map<String, Object> tableData = new HashMap<>();
             for (TableInfoEntity entity : entities) {
                 Row row = sheet.getRow(entity.getRowNum());
                 if(row==null){continue;}
                 Cell cell = row.getCell(entity.getColNum());
                 Object cellValue = getOperationCellValue(cell);
                 tableData.put("R"+entity.getRowNum().toString()+"L"+entity.getColNum().toString(),cellValue);
             }
             in.close();
             return tableData;
         } catch (StandardException e) {
             log.debug("export excel for {}",e.getMessage());
             throw new StandardException(e.getMessage());
         }catch (Exception e) {
             log.debug("export excel for {}",e.getMessage());
             throw new StandardException("表格类型不匹配,请选择正确的表格模板");
         }
     }
     /**
      * 解析复杂单元格
      * @param cell
      * @return
      */
     public static  Object getOperationCellValue(Cell cell){
         Object value = null;
         switch (cell.getCellType()) {
             case STRING:
                 value = CustomUtils.stringTrim(cell.getRichStringCellValue().getString());
                 break;
             case NUMERIC:
                 String valueNum = String.valueOf(cell.getNumericCellValue());
                 if("0".equals(valueNum)){
                     value = 0;
                 }else{
                     BigDecimal bigDecimal = new BigDecimal(valueNum);
                     bigDecimal = bigDecimal.setScale(4, BigDecimal.ROUND_HALF_UP);
                     value = bigDecimal;
                 }
                 break;
             case BOOLEAN:
                 value = cell.getBooleanCellValue();
                 break;
             //如果单元格为空  返回"" map获取值避免报错
             case BLANK:
                 value = "";
                 break;
             default:
                 break;
         }
         return value;
     }
     /**
      * 描述:对二维表表格中数值进行格式化
      */
     public static  Object getCellValue(Cell cell){
         Object value = null;
         switch (cell.getCellType()) {
             case STRING:
                 // 去除单元格中的空格  字符串
                 value = CustomUtils.stringTrim(cell.getRichStringCellValue().getString());
                 if(StringUtils.isBlank(value.toString())){
                     value = null;
                 }
                 break;
             case NUMERIC:
                 //日期
                 if("m/d/yyyy".equals(cell.getCellStyle().getDataFormatString())){
                     value = cell.getDateCellValue();
                 }else{
                     //获取数字类型
                     value = cell.getNumericCellValue();
                 }
                 break;
             case BOOLEAN:
                 value = cell.getBooleanCellValue();
                 break;
              //如果单元格为空  返回null
             case BLANK:
                 value = null;
                 break;
             default:
                 break;
         }
         return value;
     }
    
     /**
      * 判断指定的单元格是否是合并单元格
      * @param sheet
      * @param row 行下标
      * @param column 列下标
      * @return
      */
     private static boolean isMergedRegion(Sheet sheet,int row ,int column) {
         int sheetMergeCount = sheet.getNumMergedRegions();
         for (int i = 0; i < sheetMergeCount; i++) {
             CellRangeAddress range = sheet.getMergedRegion(i);
             int firstColumn = range.getFirstColumn();
             int lastColumn = range.getLastColumn();
             int firstRow = range.getFirstRow();
             int lastRow = range.getLastRow();
             if(row >= firstRow && row <= lastRow){
                 if(column >= firstColumn && column <= lastColumn){
                     return true;
                 }
             }
         }
         return false;
     }
     /**
      * 获取合并单元格的值
      * @param sheet 表格
      * @param row   行
      * @param column  列
      * @return
      */
     public static String getMergedRegionValue(Sheet sheet ,int row , int column){
         int sheetMergeCount = sheet.getNumMergedRegions();
         for(int i = 0 ; i < sheetMergeCount ; i++){
             CellRangeAddress ca = sheet.getMergedRegion(i);
             int firstColumn = ca.getFirstColumn();
             int lastColumn = ca.getLastColumn();
             int firstRow = ca.getFirstRow();
             int lastRow = ca.getLastRow();
    
             if(row >= firstRow && row <= lastRow){
    
                 if(column >= firstColumn && column <= lastColumn){
                     Row fRow = sheet.getRow(firstRow);
                     Cell fCell = fRow.getCell(firstColumn);
                     return getCellValue(fCell).toString() ;
                 }
             }
         }
         return null ;
     }
    

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值