用easypoi实现数据库的Excel导入导出操作

用easypoi实现数据库的Excel导入导出操作

Apache POI 简介

ApachePOI是用Java编写的免费开源的跨平台的JavaAPI,ApachePOI提供API给Java程序对MicrosoftOffice格式档案读和写的功能,其中使用最多的就是使用POI操作Excel文件。

使用:https://blog.csdn.net/qq_44316726/article/details/105495959

缺点:

​ 1.对于复杂的Excel模板样式需要编写大量的代码实现

​ 2.大数据量的读取/导成效率低下,甚至可能内存溢出

EasyPoi简介

为了解决上述poi的缺点,国内有很多开源项目对poi进行了封装,大大减少代码量,使其能够更简单的被我们使用并提高开发效率,例如EasyPoi,Excel4J,HuTools等优秀的开源项目。我们这次以EasyPoi为例

easypoi功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员就可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板导出,通过简单的注解和模板语言(熟悉的表达式语法),完成以前复杂的写法。

开发文档:http://doc.wupaas.com/docs/easypoi/easypoi-1c0u4mo8p4ro8

Maven依赖

		<dependency>
              <groupId>cn.afterturn</groupId>
              <artifactId>easypoi-spring-boot-starter</artifactId>
              <version>4.3.0</version>
         </dependency>

@Excel注解,在需要导出的实体类中的字段上加上

 	@ApiModelProperty(value = "出生日期")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "Asia/Shanghai")
    @Excel(name = "出生日期", width = 20, format = "yyyy-MM-dd",suffix = "年") 
	// 在导出的Excel表中会有个 “出生日期” 的列
	// 每一行数据后都用 “年” 
    private LocalDate birthday;

@ExcelEntity 注解,在实体类中还存在子实体类在其上加上

 	@ApiModelProperty(value = "民族")
    @TableField(exist = false)
    @ExcelEntity(name = "民族")
    private Nation nation;

在Nation实体类中需要导出的字段上加上: @Excel

	@ApiModelProperty(value = "民族")
    @Excel(name = "民族")
    @NonNull
    private String name;

导出接口:

编写Controller

@Api(tags = "Excel导入导出")
@RestController
@RequestMapping("/api")
public class ExcelController {

  	@ApiOperation("员工数据导出Excel")
    // produces = "application/octet-stream" :设置用流的形式输出
    @GetMapping(value = "/excel/export", produces = "application/octet-stream")
    public void exportEmpToExcel(HttpServletResponse response) { 
        List<Employee> list = employeeService.getEmployeeAll(); // 查询数据库得到全部数据
       
        // 1 : 在Excel表中的表头 (第一行) 2 :sheet名字  3 : 导出 Excel 类型 HSSF 03版 导出数据的比 XSSF 07版的速度要快 ,且 HSSF 03版 兼容性高
        ExportParams params = new ExportParams("员工数据表", "员工表", ExcelType.HSSF);
        
        // 使用EasyPoi提供的工具类:ExcelExportUtil.exportExcel(ExportParams entity, Class<?> pojoClass,Collection<?> dataSet):  params, Employee.class, list ;;  得到 Workbook:POI 提供的工作铺 对象
        Workbook workbook = ExcelExportUtil.exportExcel(params, Employee.class, list);
//        ServletOutputStream out = null;
        try {
            // 流形式
            response.setHeader("content-type", "application/octet-stream");
            // 防止中文乱码
            response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode("员工表", "UTF-8") + ".xls");
            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                workbook.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

在这里插入图片描述

导入接口:

在处理 政治面貌、部门… 这些用通过实体类中的子实体类中的名字在输入数据库的时候只需要设置他们的 Id 所以:

  1. 在拿到这些值之后通过这个名字到数据库查找得到每一个的 id 在进行设置 ;这个方法对数据库的负载过大:这里一条数据需要查 5 次数据库 ,这里不推荐使用

  2. 这里的子实体类中的name属性不会经常变动 ,如 民族这个 ,所以这里我们可以来重写 Equals HashCode 方法 ,在获取到这个把name之后表示拿到的这个实体类是唯一的,因为唯一所以我们就能拿到唯一的 id ,再进行设置

    使用@EqualsAndHashCode(callSuper = false, of = “name”):不使用EqualsAndHashCode方法,并用 name 属性来重写,使用@RequiredArgsConstructor来加入使用name属性的有参构造 Nation(String)来唯一建立这个对象,设置属性name非空

@Data
@RequiredArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = false, of = "name") //
@Accessors(chain = true)
@TableName("t_nation")
@ApiModel(value="Nation对象", description="")
public class Nation implements Serializable {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "id")
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    @ApiModelProperty(value = "民族")
    @Excel(name = "民族")
    @NonNull
    private String name;
}
controller类

    @ApiOperation("员工数据Excel导入数据库")
    @PostMapping(value = "/excel/import", produces = "application/octet-stream")
    public RespBean importExcel(MultipartFile filename) {

        ImportParams params = new ImportParams();
        // 去掉标题行
        params.setTitleRows(1);
		//只需查这一次
        List<Nation> nationList = notionService.getNotions();
        List<PoliticsStatus> politicsStatusList = politicsService.getPoliticsStatus();
        List<Department> departmentList = departmentService.getList();
        List<JobLevel> joblevelList = jobLevelService.getAll();
        List<Position> positionList = positionService.getPosList();

        try {
            List<Employee> list = ExcelImportUtil.importExcel(filename.getInputStream(), Employee.class, params);
            list.forEach(employee -> {
                // 民族id
                employee.setNationId(nationList.get(nationList.indexOf(new Nation(employee.getNation().getName()))).getId());
                // 政治面貌id
                employee.setPoliticId(politicsStatusList.get(politicsStatusList.indexOf(new PoliticsStatus(employee.getPoliticsStatus().getName()))).getId());
                // 部门id
                employee.setDepartmentId(departmentList.get(departmentList.indexOf(new Department(employee.getDepartment().getName()))).getId());
                // 职称id
                employee.setJobLevelId(joblevelList.get(joblevelList.indexOf(new JobLevel(employee.getJoblevel().getName()))).getId());
                // 职位id
                employee.setPosId(positionList.get(positionList.indexOf(new Position(employee.getPosition().getName()))).getId());
            });
            if (employeeService.saveBatch(list)) {//利用mybatisplus中的saveBatch方法批量插入
                return RespBean.success("导入员工信息成功!");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }
        return RespBean.warning("导入员工信息失败!");
    }

功!");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
}
return RespBean.warning(“导入员工信息失败!”);
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

crabin_lpb

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值