前言

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

常用注解

@Excel 作用到filed上面,是对Excel一列的一个描述
@ExcelCollection 表示一个集合,主要针对一对多的导出,比如一个老师对应多个科目,科目就可以用集合表示
@ExcelEntity 表示一个继续深入导出的实体,但他没有太多的实际意义,只是告诉系统这个对象里面同样有导出的字段
@ExcelIgnore 和名字一样表示这个字段被忽略跳过这个导出
@ExcelTarget 这个是作用于最外层的对象,描述这个对象的id,以便支持一个对象可以针对不同导出做出不同处理

详细见:http://easypoi.mydoc.io/#text_186901

使用

以Springboot为实例

导出功能

1.引入依赖

    <dependency>
        <groupId>cn.afterturn</groupId>
        <artifactId>easypoi-base</artifactId>
        <version>3.2.0</version>
    </dependency>
    <dependency>
        <groupId>cn.afterturn</groupId>
        <artifactId>easypoi-web</artifactId>
        <version>3.2.0</version>
    </dependency>
    <dependency>
        <groupId>cn.afterturn</groupId>
        <artifactId>easypoi-annotation</artifactId>
        <version>3.2.0</version>
    </dependency>`

2.准备返回的实体类对象并添加合适的注解

@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserExportVo {
    /**
     * name: 表格的名称
     * width: 表格的宽度
     */
    @Excel(name = "用户ID")
    private String id;

    @Excel(name = "账号", width = 20)
    private String userName;

    @Excel(name = "姓名")
    private String realName;

    @Excel(name = "性别")
    private String gender;

    @Excel(name = "手机号码", width = 20)
    private String phoneNumber;

    @Excel(name = "邮箱地址", width = 20)
    private String mailAddress;

    //将id与中文内容替换,导入和导出是时会自动取反
    @Excel(name = "状态", replace = {"未激活_0", "激活_1", "冻结_2"})
    private String userStatus;

    @Excel(name = "部门", width = 20)
    private String departmentName;

}

3.导出接口的实现

@ApiOperation("导出用户")
    @GetMapping(value = "/outputUser", produces = "application/octet-stream")
    public void outPutUser(HttpServletResponse response){

        List<UserExportVo> userList = userService.outputUser();
        //设置表格的基本信息(标题,sheet名称,格式:(HSSF)当前采用的是03版的格式,改格式响应快且兼容性好)
        ExportParams exportParams = new ExportParams();
        exportParams.setSheetName("用户信息");
        exportParams.setTitle("员工信息");
        exportParams.setType(ExcelType.HSSF);

        /**
         * 将内容导出
         * arg1:ExportParams,涵盖了表格基本格式以及样式等
         * arg2:返回对象的类
         * arg3:内容
         */
        Workbook sheets = ExcelExportUtil.exportExcel(exportParams,UserExportVo.class, userList);

        //定义一个流,用作流式输出
        ServletOutputStream outputStream = null;
        try {
            //使用流的形式传输
            response.setHeader("content-type", "application/octet-stream");
            //防止中文乱码
            response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode("员工表.xls", "UTF-8"));
            outputStream = response.getOutputStream();
            sheets.write(outputStream);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(null!=outputStream){
                try {
                    //关闭流
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

值得注意的是,在导出过程中使用流的形式导出,需要考虑到中文是否乱码的问题

导入功能

1.实现导入接口

@ApiOperation("导入文件")
    @PostMapping("/inputUser")
    public RespBean inputUser(MultipartFile file){

        ImportParams importParams = new ImportParams();
        importParams.setTitleRows(1);//去掉标题行
        List<PUserinfo> pUserinfoList = new ArrayList<>();
        try {
            //用流的方式导入数据,获取到当前导入的内容
            List<UserStreamVo> userList = ExcelImportUtil.importExcel(file.getInputStream(), UserStreamVo.class, importParams);
            //添加业务校验(手机号格式校验,非空校验等),此处可以增加数据错误定位
            if(userList==null || userList.size()==0){
                return RespBean.error("无数据");
            }
            //双重检索,防止数据库多次查询,避免缓存击穿
            Map departmentHashMap = redisTemplate.opsForHash().entries("departmentHashMap");
            if(departmentHashMap.isEmpty()){
                synchronized (this){
                    departmentHashMap = redisTemplate.opsForHash().entries("departmentHashMap");
                    if(departmentHashMap.isEmpty()){
                        //查询数据库
                        List<PDepartment> allDepartments = departmentService.list();
                        for(PDepartment department : allDepartments){
                            departmentHashMap.put(department.getName(), department.getId());
                        }
                        redisTemplate.opsForHash().putAll("departmentHashMap", departmentHashMap);
                    }
                }
            }

            String departmentId;
            for(UserStreamVo userinfo : userList){
                //必须在循环里面new对象,否则会导致所有插入到数据库的对象变成最后一条
                PUserinfo pUserinfo = new PUserinfo();
                pUserinfo.setId(userinfo.getId());
                pUserinfo.setGender(userinfo.getGender());
                pUserinfo.setPassword(uuidUtil.createRandomId().substring(0,9));
                pUserinfo.setRealName(userinfo.getRealName());
                pUserinfo.setUserName(userinfo.getUserName());
                pUserinfo.setUserStatus(userinfo.getUserStatus());
                pUserinfo.setMailAddress(userinfo.getMailAddress());
                pUserinfo.setPhoneNumber(userinfo.getPhoneNumber());
                departmentId = (String) departmentHashMap.get(userinfo.getDepartmentName());
                pUserinfo.setDepartmentId(departmentId);
                pUserinfo.setPositionId("1");
                pUserinfoList.add(pUserinfo);
            }
            if(userService.saveBatch(pUserinfoList)){
                return RespBean.success("导入成功");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return RespBean.error("导入失败");
    }
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐