云e办(后端)——导入导出员工数据(EasyPoi注解使用)

云e办(后端)——导入导出员工数据(EasyPoi注解使用)

在我们日常工作中经常需要导入和导出我们的员工数据,所以本次我们完善此功能

在这里插入图片描述

一、EasyPoi注解使用

介绍:

poi :poi就是批量的操作文件或数据的导入以及导出 ,但是因为其使用起来需要过多的编辑代码,所以我们在此采用easypoi。

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

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

特点:

设计精巧,使用简单
接口丰富,扩展简单
默认值多,write less do more
AbstractView支持,web导出可以简单明了

二、导出员工数据前期准备

1、添加依赖
<!--easy poi依赖-->
<dependency>
   <groupId>cn.afterturn</groupId>
   <artifactId>easypoi-spring-boot-starter</artifactId>
   <version>4.1.3</version>
</dependency>

2、修改员工类

EasyPoi最大的特点是:可以通过注解定义导出的字段。

  • 普通属性:员工类使用注解@Excel 定义了需要导出的属性, name 为导出的列名, width 可以定义列的宽度, format可以定义导入和导出的日期格式

  • 实体类对象作为属性:员工类中还有其他类作为属性,例如民族,政治面貌,职称,职位等。这些使用@ExcelEntity 标记为实体类。
    并且在该实体类对象中加入注解 @Excel即可。

修改pojo包下的Employee类
employee类是员工类:

/**
     * @Excel 注解的部分参数:
     * name:导出到excel的列名
     * width:是导入到excel时,表格的宽度
     * suffix = "年"  后缀,比如说工龄是1年
     */
    ----------------------   ----------------------
    /**
     * 民族、婚姻政治面貌、部门、职位等肯定不是导入导出id,而是导出对应的表中的名字
     * 以民族为例子:
     * 民族nation是一个对象,也是POJO类,那怎么定义实体类呢?
     * 第一步:加入注解 @ExcelEntity
     * 第二部:修改POJO类 加入:@Excel(name = "民族")
     *
     * -- 那么会通过注解ExcelEntity表示是一个实体类,从而导入真实的数据
     *
     */

	@ApiModelProperty(value = "入职日期")
    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "Asia/Shanghai")
    @Excel(name = "入职日期",width = 20, format = "yyyy-MM-dd")
    private LocalDate beginDate;

    @ApiModelProperty(value = "在职状态")
    @Excel(name = "在职状态")
    private String workState;

    @ApiModelProperty(value = "工号")
    @Excel(name = "工号")
    private String workID;

    @ApiModelProperty(value = "合同期限")
    @Excel(name = "合同期限",suffix = "年")
    private Double contractTerm;
    	/**
	 * 表中有很多外界id,都需要对应外界的表中。
	 * 表需要对应pojo的对象中
	 */
	@ApiModelProperty(value = "民族")
	//在正常的员工表中是不存在的
	@TableField(exist=false)
	@ExcelEntity(name = "民族")
	private Nation nation;
	
	
	@ApiModelProperty(value = "政治面貌")
	@TableField(exist = false)
	@ExcelEntity(name = "政治面貌")
	private PoliticsStatus politicsStatus;

    @ApiModelProperty(value = "部门")
    @TableField(exist = false)
    @ExcelEntity(name = "部门")
    private Department department;

    @ApiModelProperty(value = "职称")
    @TableField(exist = false)
    @ExcelEntity(name = "职称")
    private Joblevel joblevel;

    @ApiModelProperty(value = "职位")
    @TableField(exist= false)
    @ExcelEntity(name = "职位")
    private Position position;

    @ApiModelProperty(value = "工资账套")
    @TableField(exist = false)
    private Salary salary;


再去修改nation类中的代码:

package com.xxxx.server.pojo;

import cn.afterturn.easypoi.excel.annotation.Excel;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;

@Data
//of: 要重写的属性。 以name重写了Equals和hashcode。表示以name重写了equals/hashcode以及写完了
//当新建对象的时候,可以直接把name放进去,表示得到一个唯一的。:有参构造
@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 = "民族")
    //非空的,写新的有参构造时,name是必填的。
    @NonNull
    private String name;
}


在这里插入图片描述

三、导出数据

controller
  • 获取员工的数据
  • 准备导出的参数(表名、sheet名字、导出的excel类型) 【ExportParams类准备参数】
  • 将数据导出(导出的参数、实体类对象、导出的具体数据)【ExcelExporUtil导出工具类】
  • 通过流的形式进行导出【Response】
    //通过流的形式传出去:httpServletResponse response
    // produces通过流形式传输,解决乱码
    @ApiOperation(value = "导出员工数据")
    @GetMapping(value = "/export",produces = "application/octet-stream")
    public void exportEmployee(HttpServletResponse response) throws UnsupportedEncodingException {
        //获取当前员工的数据-具体的数据
        List<Employee> list = iEmployeeService.getEmployee(null);
        /**
         * 导出的参数:
         *  导出员工的数据:(文件名的名字,sheet表名,excel的版本)
         *  excel :
         *  03: HSSF - 提供读写Microsoft Excel XLS格式档案的功能。03打不开07
         *  07: XSSF - 提供读写Microsoft Excel OOXML XLSX格式档案的功能。07能打开03
         *
         *   03的HSSF比07的XSSF优点:
         *      1.速度快
         *      2.兼容性好。03打不开07, 07能打开03
         */
        ExportParams params = new ExportParams("员工表","sheet员工表", ExcelType.HSSF);

        /**
         * ExcelExportUtil导出工具类:(导出的参数、对象类名.class、具体的数据)
         *  返回的是Workbook。是poi的一个类。相当于工作簿(工作簿就是一个Excel)
         */
        Workbook book = ExcelExportUtil.exportExcel(params, Employee.class, list);

        /**
         * response。输出流形式 输出workboo
         *
         * 导出需要一些请求头的响应信息
         * 防止中文乱码
         */
        ServletOutputStream out = null;
        try{
            //流形式,设置一个头
            response.setHeader("content-type","application/octet-stream");
            //防止中文乱码
            response.setHeader("content-disposition","attachment;filename="+
                    URLEncoder.encode("员工表.xls","UTF-8"));
            out = response.getOutputStream();
            book.write(out);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try{
                out.flush();
                out.close();
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }

四、导入员工

导入时,因为在我们的excel表中所给出的民族name,政治面貌name等,但我们需要获取到对应的民族id,政治面貌id,职称id,职位id等。有两种方法

  • 根据name属性的值去数据库查询对应的id,显然在循环里面不断去查询数据库非常消耗性能,不推荐
  • 取巧:重写equals和hashCode方法,只要name属性的值一致就表示对象一致。前提是name属性的值基本不会变动。
    (例如民族。民族、政治面貌都是固定不变的。那么name属性是唯一的,那么就能根据name属性能知道创建对象的对象是唯一的。对象是唯一的话,那么就可以拿到对象的id)

我们选择第二种方法实现

1、导入准备:重写equals和hashCode方法

在这里插入图片描述

2、controller。
@ApiOperation(value = "导入员工数据")
    @PostMapping("/import")
    public RespBean importEmployee(MultipartFile file){
        //创建导入对象
        ImportParams params = new ImportParams();
        //去掉标题第一行
        params.setTitleRows(1);
  /**
         * 导入 流的形式、POJO对象类的字节码、数据--- 返回的是数据
         *
         * 导入完成后,pojo.Employee-nation是有值的
         * pojo.nation拿到的就是name 是因为:
         *  Excel注解,ExcelEntiy注解:
         *      能通过汉族名字获取到它是nation.ExcelEntiy就知道了是对象里面的,从而得到name
         *  如何获得name的id呢?
         *
         *      for循环
         *      重写了hashcode方法,也准备了有参构造。
         *      1.从excel导入的数据中,拿到了nation对象,对象里面有name,id是空的
         *      2.查询所有的nationList,获取对象索引下标:重写了equals和hashcode,
         *          通过name名字去nationList比较。能获取一样的对象.从而得到下标。
         *      3.通过nationList.get(下标).getId() 获取完整的对象:有id,name\
         *      4.在从id,name中获取id。 将id放入到employee中。
         *
         *  if插入:saveBatch批量插入。 插入集合
         *
         */
        List<Nation> nationlList = nationService.list();
        List<PoliticsStatus> politicsStatusList = politicsStatusService.list();
        List<Department> departmentList = departmentService.list();
        List<Joblevel> joblevelList = joblevelService.list();
        List<Position> positionList = positionService.list();
        try{
            List<Employee> list = ExcelImportUtil.importExcel(file.getInputStream(), Employee.class, params);
            list.forEach(employee -> {
                //民族id
                employee.setNationId(nationlList.get(nationlList.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 (iEmployeeService.saveBatch(list)){
                return RespBean.success("导入成功!");
            }
            return RespBean.error("导入失败!");
        } catch (Exception e){
            e.printStackTrace();
        }
        return RespBean.error("导入失败!");
    }


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
后端excel导入导出的实现可以通过以下步骤进行: 1. 创建一个Java实体对象,用于与导入Excel表格对应,并在每个字段上添加对应的Excel导入注解,如@ExcelImport。 2. 创建一个Java类,用于处理导入导出的操作。在该类中,可以使用第三方库或自定义方法来实现Excel导入导出功能。 3. 对于Excel导入,可以通过读取Excel文件,解析每个单元格的数据,并将数据映射到Java实体对象中。可以使用Apache POI或EasyExcel等库来处理Excel文件。 4. 对于Excel导出,可以根据需要创建一个Excel模板,包含所需的表头信息和样式。然后,根据Java实体对象的数据,将数据填充到Excel模板中,并生成最终的Excel文件。同样,可以使用Apache POI或EasyExcel等库来处理Excel文件。 下面是一个示例代码片段,展示了如何在后端实现Excel导入导出: ``` // 导入Excel @PostMapping("/import") public void importExcel(@RequestParam("file") MultipartFile file) { // 读取Excel文件 List<ImportUser> userList = ExcelUtils.importExcel(file, ImportUser.class); // 处理导入数据 // ... } // 导出Excel @GetMapping("/export") public void exportExcel(HttpServletResponse response) { // 查询要导出数据 List<ExportUser> userList = userService.getAllUsers(); // 创建Excel模板 ExcelTemplate template = new ExcelTemplate(ExportUser.class); template.createHeaderRow(); // 填充数据Excel模板 for (ExportUser user : userList) { template.createDataRow(user); } // 导出Excel文件 ExcelUtils.exportExcel(response, template, "用户表.xlsx"); } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

真真最可爱

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

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

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

打赏作者

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

抵扣说明:

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

余额充值