• Java工具类Hutool使用


    Java工具类Hutool使用

    前言

    • 在开发的过程中,我们需要一些工具类实现某些特殊处理,例如字符串格式处理,日期处理,文件处理等操作。如果在传统的开发过程中,我们将自己开发一些工具类用于实现这些功能。但自己开发可能就会在不经意间由于代码的不严谨,引发某些bug。而当我们使用hutool 提供和工具库,就能有效提高开发效率。
    • 应用官方的介绍:
    • Hutool是一个Java工具包类库,对文件、流、加密解密、转码、正则、线程、XML等JDK方法进行封装,组成各种Util工具类
    • 官网:hutool.cn/
    • 源码:https://gitee.com/dromara/hutool

    基础功能使用

    引入依赖

    • 添加hutool 的依赖,该依赖需要指定版本,该是一个Hutool的集成打包产品,由于考虑到“懒人”用户及分不清各个模块作用的用户,“无脑”引入hutool-all模块是快速开始和深入应用的最佳方式。

    • 
          cn.hutool
          hutool-all
          5.8.5
      
      
      • 1
      • 2
      • 3
      • 4
      • 5

    使用

    • 当引入hutool依赖后,即可想使用我们在工程中新建的工具类一般使用由hutool 提供的工具类,无需再进行其余配置,真正做到引入可用。

    • //当前时间
      Date date = DateUtil.date();
      //当前时间
      Date date2 = DateUtil.date(Calendar.getInstance());
      //当前时间
      Date date3 = DateUtil.date(System.currentTimeMillis());
      //当前时间字符串,格式:yyyy-MM-dd HH:mm:ss
      String now = DateUtil.now();
      //当前日期字符串,格式:yyyy-MM-dd
      String today= DateUtil.today();
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
    • hutool 对日期进行了非常详细的封装,可以有效避免我们自己的日期格式出现混乱的情况。而且hutool 为我们提供了多个日期格式解析,转换成yyyy-MM-dd HH:mm:ss 格式,同时我们可以引用这些日期格式:

    • yyyy/MM/dd HH:mm:ss
      yyyy.MM.dd HH:mm:ss
      yyyy年MM月dd日 HH时mm分ss秒
      yyyy-MM-dd
      yyyy/MM/dd
      yyyy.MM.dd
      HH:mm:ss
      HH时mm分ss秒
      yyyy-MM-dd HH:mm
      yyyy-MM-dd HH:mm:ss.SSS
      yyyyMMddHHmmss
      yyyyMMddHHmmssSSS
      yyyyMMdd
      EEE, dd MMM yyyy HH:mm:ss z
      EEE MMM dd HH:mm:ss zzz yyyy
      yyyy-MM-dd'T'HH:mm:ss'Z'
      yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
      yyyy-MM-dd'T'HH:mm:ssZ
      yyyy-MM-dd'T'HH:mm:ss.SSSZ
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
    • String dateStr = "2017-03-01";
      Date date = DateUtil.parse(dateStr);
      
      //结果 2017/03/01
      String format = DateUtil.format(date, "yyyy/MM/dd");
      
      //常用格式的格式化,结果:2017-03-01
      String formatDate = DateUtil.formatDate(date);
      
      //结果:2017-03-01 00:00:00
      String formatDateTime = DateUtil.formatDateTime(date);
      
      //结果:00:00:00
      String formatTime = DateUtil.formatTime(date);
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
    • 字符串工具,随机uuid 工具也是日常使用频繁的工具类:

    • //subString方法越界啥的都会报异常,还得自己判断,hutool把各种情况判断都加进来了,而且index的位置还支持负数,-1表示最后一个字符(这个思想来自于Python,如果学过Python的应该会很喜欢的),还有就是如果不小心把第一个位置和第二个位置搞反了,也会自动修正(例如想截取第4个和第2个字符之间的部分也是可以的哦~) 举个栗子
      String str = "abcdefgh";
      String strSub1 = StrUtil.sub(str, 2, 3); //strSub1 -> c
      String strSub2 = StrUtil.sub(str, 2, -3); //strSub2 -> cde
      String strSub3 = StrUtil.sub(str, 3, 2); //strSub2 -> c
      
      • 1
      • 2
      • 3
      • 4
      • 5
    • //唯一字符串
      //生成的UUID是带-的字符串,类似于:a5c8a5e8-df2b-4706-bea4-08d0939410e3
      String uuid = IdUtil.randomUUID();
      
      //生成的是不带-的字符串,类似于:b17f24ff026d40949c85a24f4f375d42
      String simpleUUID = IdUtil.simpleUUID();
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

    基于Hutool的excel开发

    引入依赖

    • excel 包完全依赖于hutool 工具包,不需要额外的引入,hutool all中已经包含了hutool 的全部工具包

    •         
              
                  cn.hutool
                  hutool-all
                  5.7.22
              
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

    开发

    • 首先确定我们要对那些表进行数据的导入导出,这里的建议是对数据更改不频繁的表进行数据的导入导出,而且对于数据的唯一性要求不高,否则在进行数据导入的过程中,需要进行复杂的逻辑处理。这里我使用的是组织的用户信息表,该表的数据只有组织自己进行维护,就可以使用标准导入。

    • /**
       * 组织用户信息表
       * @TableName cf_group_user
       */
      @TableName(value ="cf_group_user")
      @Data
      public class GroupUser implements Serializable {
          /**
           * id
           */
          @TableId(type = IdType.AUTO)
          private Integer id;
      
          /**
           * 组织id
           */
          private Integer groupId;
      
          /**
           * 姓名
           */
          @NotBlank(message = "姓名不可为空")
          private String nickname;
      
          /**
           * 性别(0:默认,1:男,2:女)
           */
          @NotBlank(message = "性别不可为空")
          private Integer sex;
      
          /**
           * 出生日期
           */
          @NotBlank(message = "出生日期不可为空")
          private Date bornTime;
      
          /**
           * 形象照片
           */
          @NotBlank(message = "形象照片不可为空")
          private String photo;
      
          /**
           * 家庭地址
           */
          @NotBlank(message = "家庭地址不可为空")
          private String homeAddress;
      
          /**
           * 联系电话
           */
          @NotBlank(message = "联系电话不可为空")
          private Integer mobile;
      
          /**
           * 实名信息
           */
          private String authId;
      
          /**
           * 职务信息
           */
          @NotNull(message = "职务不可为空")
          private String post;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
    • create table cf_group_user
      (
          id           int unsigned auto_increment comment 'id'
              primary key,
          group_id     int unsigned               not null comment '组织id',
          nickname     char(30)                   not null comment '姓名',
          sex          tinyint unsigned           not null comment '性别(1:男,2:女)',
          born_time    datetime                   not null comment '出生日期',
          photo        varchar(255)               not null comment '形象照片',
          home_address varchar(255)               not null comment '家庭地址',
          mobile       int                        not null comment '联系电话',
          post         varchar(255)               not null comment '职务信息'
      )
          comment '组织用户信息表' collate = utf8_unicode_ci;
      
      create index auth_id
          on cf_group_user (auth_id);
      
      create index group_id
          on cf_group_user (group_id);
      
      create index mobile
          on cf_group_user (mobile);
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
    • 在确定表后,我们需要选取那些字段是我们需要使用的,在excel 表中进行展示,需要用户填入,根据字段构建反射。

    实现

    • 在工程中先确定使用的字段构建模板,根据字段构建excel 的模板。这里的示例如下:
      
      • 1
    • //controller层
      //返回模板
          @RequestMapping("/getExcelTemplate")
          public void getExcelTemplate(HttpServletResponse response) {
              groupUserService.getExcelTemplate(response);
          }
      
      //sevice层
      void getExcelTemplate(HttpServletResponse response);
      
      //impl
      @Override
          public void getExcelTemplate(HttpServletResponse response) {
              try {
                  // 1 读取对象
                  final ExcelReader reader = ExcelUtil.getReader(ResourceUtil.getStream("templates/group.xlsx"));
                  List> lists = reader.read();
                  ExcelWriter writer = ExcelUtil.getWriter(true);
                  writer.write(lists);
                  response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode("group.xlsx", "UTF-8"));
                  response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
                  // 2 写出对象
                  ServletOutputStream outputStream = response.getOutputStream();
                  // 通过IO写出我们的表格对象
                  writer.flush(outputStream, true);
                  writer.close();
                  IoUtil.close(outputStream);
              } catch (IOException e) {
                  log.error("EducationServiceImpl [export] 输出到响应流失败", e);
                  throw new APIException("导出Excel异常");
              }
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
    • 这里我使用的是三层构建,在controller 层中暴露接口,进行调用,所有的具体实现进行抽象。

    • //导入信息
          @RequestMapping("/importStudent")
          public R importStudent(@RequestParam MultipartFile file) {
              try {
                  boolean userInfo = groupUserService.getUserInfo(file);
                  if(userInfo) return R.success();
              } catch (IOException e) {
                  log.error("EducationController [getEducation] 获取输入流失败", e);
                  throw new APIException("获取输入流失败");
              }
              return R.error();
          }
      
      //导出信息
          @RequestMapping("/export")
          public void export(@RequestBody PageVo pageVo, HttpServletResponse response) {
              groupUserService.export(pageVo, response);
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
    • void export(PageVo pageVo, HttpServletResponse response);
      
      boolean getUserInfo(MultipartFile file) throws IOException;
      
      @Override
          public void export(PageVo pageVo, HttpServletResponse response) {
              // 从数据库查出数据对象封装成map
              final List> educationList = this.page(new Page<>(pageVo.getPage(), pageVo.getLimit()), Wrappers.lambdaQuery()).getRecords()
                      .stream()
                      // 封装成 Map 并且放入 List
                      .map(item -> {
                          final Map map = new LinkedHashMap<>();
                          // 错误,这里需要根据表中字段名称进行命名
                          map.put("nickname", item.getNickname());
                          map.put("sex", item.getSex());
                          map.put("mobile", item.getMobile());
                          map.put("bornTime", item.getBornTime());
                          map.put("homeAddress", item.getHomeAddress());
                          map.put("post", item.getPost());
                          return map;
                      })
                      .collect(Collectors.toList());
              // 准备将数据集合封装成Excel对象
              ExcelWriter writer = ExcelUtil.getWriter(true);
              // 通过工具类创建writer并且进行别名
              writer.addHeaderAlias("nickname", "姓名");
              writer.addHeaderAlias("sex", "性别( 0 表示男 , 1 表示 女)");
              writer.addHeaderAlias("mobile", "电话");
              writer.addHeaderAlias("bornTime", "出生日期");
              writer.addHeaderAlias("homeAddress", "家庭地址");
              writer.addHeaderAlias("post", "职位");
              // 准备将对象写入我们的 List
              writer.write(educationList, true);
              try {
                  // 获取我们的输出流
                  final OutputStream output = response.getOutputStream();
                  response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode("group.xlsx", "UTF-8"));
                  response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
                  writer.flush(output, true);
                  writer.close();
                  // 这里可以自行关闭资源或者写一个关闭资源的工具类
                  IoUtil.close(output);
              } catch (IOException e) {
                  log.error("EducationServiceImpl [export] 输出到响应流失败", e);
                  throw new APIException("导出Excel异常");
              }
          }
      
          @Override
          public boolean getUserInfo(MultipartFile file) throws IOException {
              ExcelReader reader = ExcelUtil.getReader(file.getInputStream());
              HashMap head = new HashMap<>(6);
              head.put("姓名","nickname");
              head.put("性别( 0 表示男 , 1 表示 女)","sex");
              head.put("电话","mobile");
              head.put("出生日期", "bornTime");
              head.put("家庭地址","homeAddress");
              head.put("职位","post");
              reader.setHeaderAlias(head);
              List read = reader.read(0, 1, GroupUser.class);
              Group group = groupService.getOne(new QueryWrapper().eq("uid", UserConstant.USER_ID));
              for (GroupUser user : read) {
                  user.setGroupId(group.getId());
                  //TODO 默认图片
                  user.setPhoto("https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png");
                  user.setStatus(1);
                  user.setCreateTime(new DateTime());
                  if(!this.save(user))return false;
              }
              return true;
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
    • 使用hutool 进行excel 处理的时候,需要自己定义字段与excel 表头见的映射关系,这一点是比较麻烦的。但相比于其他excel的使用方式,这是一种非常简单的实现。

  • 相关阅读:
    某央企下属电子集团组织提升咨询项目成功纪实
    连续子数组的最大和
    Kruskal算法
    计算摄像技术01 - 摄像技术基础知识
    CTC 技术介绍概述——啃论文系列
    使用OpenVINO实现飞桨版PGNet推理程序
    使用神经网络进行预测,图神经网络 社交网络
    ElasticSearch的快速安装和使用
    如何把项目部署到云服务器
    vue3 +element-plus中避免一打开表单的下拉选择的change事件自动校验问题
  • 原文地址:https://blog.csdn.net/Andrew_Chenwq/article/details/132915275