EasyExcel简单使用

EasyExcel简单使用

​ 之前一直用的Apache POI来做数据的导入导出,但听说阿里的EasyExcel也拥有POI的功能的同时,在处理大数据量的导入导出的时候性能上比POI更好,所以就来尝试使用一下

导入Maven依赖:
xml 复制代码
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.2.1</version> <!-- 请检查并使用最新稳定版本 -->
</dependency>
导出数据功能
导出模型类

​ 定义一个导出数据模型类,用于设置excel文件的格式,通过注解的方式可以定义excel中的格式
@ColumnWidth(20) 设置excel中列的宽度为20;

@HeadStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER) 设置文本内容是否居中;

@HeadFontStyle(bold = BooleanEnum.FALSE) 设置字体是否加粗;

@ExcelProperty(value = "电话", index = 0) 设置了excel中的标题,value则是标题内容,index则是内容所在的列的位置

java 复制代码
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@ColumnWidth(20)
@HeadStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER)
@HeadFontStyle(bold = BooleanEnum.FALSE)
public class PmembersExportVO {

    @ColumnWidth(15)
    @ExcelProperty(value = "电话", index = 0)
    private String mobile;

    @ColumnWidth(15)
    @ExcelProperty(value = "姓名", index = 1)
    private String realname;

    @ColumnWidth(10)
    @ExcelProperty(value = "性别", index = 2)
    private String gender;

    @ColumnWidth(10)
    @ExcelProperty(value = "省份", index = 3)
    private String resideprovince;

    @ColumnWidth(10)
    @ExcelProperty(value = "城市", index = 4)
    private String residecity;

    @ColumnWidth(10)
    @ExcelProperty(value = "区/县", index = 5)
    private String residedist;

    @ColumnWidth(20)
    @ExcelProperty(value = "地址", index = 6)
    private String address;

    @ColumnWidth(12)
    @ExcelProperty(value = "公历生日", index = 7)
    private String birth;

    @ColumnWidth(12)
    @ExcelProperty(value = "农历生日", index = 8)
    private String yinlibirth;

    @ColumnWidth(12)
    @ExcelProperty(value = "是否闰月", index = 9)
    private String isLeapMonth;

}
controller代码
java 复制代码
    @ApiOperation("导出居士信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "weiqingview_backend_token", value = "token", required = true, dataType = "String", paramType = "header"),
            @ApiImplicitParam(name = "uniacid", value = "Unicid", required = true, dataType = "Integer", paramType = "query")
    })
    @GetMapping("/export")
    public void export(@RequestParam Map<String, Object> params, HttpServletResponse response) {
        mcMembersService.exportExcel(params, response);
    }
service代码

​ 通过查询数据库中的数据,并封装到List集合中,调用EasyExcel的write方法即可将集合中的数据写入生成excel文件供下载

java 复制代码
public void export(Map<String, Object> params, HttpServletResponse response) {

        Integer uniacid = Integer.valueOf(params.get("uniacid").toString());

        List<McMembers> mcMembersList = this.list(new QueryWrapper<McMembers>().eq("isBeliever", 1).eq("uniacid", uniacid));

        List<PmembersExportVO> pmembersExportVOList = mcMembersList.stream().map(m -> {
            PmembersExportVO pmembersExportVO = new PmembersExportVO();
            pmembersExportVO.setAddress(m.getAddress());
            pmembersExportVO.setMobile(m.getMobile());
            pmembersExportVO.setGender(ObjectUtils.isEmpty(m.getGender()) ? "" : m.getGender().equals(0) ? "女" : "男");
            pmembersExportVO.setBirth(m.getBirth());
            pmembersExportVO.setYinlibirth(m.getYinlibirth());
            pmembersExportVO.setRealname(m.getRealname());
            pmembersExportVO.setResidedist(m.getResidedist());
            pmembersExportVO.setResidecity(m.getResidecity());
            pmembersExportVO.setResideprovince(m.getResideprovince());
            pmembersExportVO.setIsLeapMonth(ObjectUtils.isEmpty(m.getIsLeapMonth()) ? "否" : m.getIsLeapMonth() == 1 ? "是" : "否");

            return pmembersExportVO;
        }).collect(Collectors.toList());


//        // 导出Excel
//        EasyExcel.write("居士信息数据.xls", PmembersExportVO.class)
                .head(headersList) // 设置表头
//                .sheet("用户信息")
//                .doWrite(pmembersExportVOList);

        // 设置响应头
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String fileName = null;
        try {
            fileName = URLEncoder.encode("居士信息数据.xlsx", "UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            EasyExcel.write(response.getOutputStream(), PmembersExportVO.class)
                    .sheet("用户信息")
                    .doWrite(pmembersExportVOList);
        } catch (UnsupportedEncodingException e) {
            log.error("导出居士信息报错 UnsupportedEncodingException:{}", e);
        } catch (IOException e) {
            log.error("导出居士信息报错 IOException:{}", e);
        }

    }
导入数据功能:
导入数据模型类

​ 我这里用的跟导出数据类基本一致,所以也就改了个类名

​ 只要用@ExcelProperty指定对应列的信息就行,其他指定格式的注解其实可以忽略

java 复制代码
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@ColumnWidth(20)
@HeadStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER)
@HeadFontStyle(bold = BooleanEnum.FALSE)
public class ImportPmcMembersDTO {

    @ColumnWidth(15)
    @ExcelProperty(value = "电话", index = 0)
    private String mobile;

    @ColumnWidth(15)
    @ExcelProperty(value = "姓名", index = 1)
    private String realname;

    @ColumnWidth(10)
    @ExcelProperty(value = "性别", index = 2)
    private String gender;

    @ColumnWidth(10)
    @ExcelProperty(value = "省份", index = 3)
    private String resideprovince;

    @ColumnWidth(10)
    @ExcelProperty(value = "城市", index = 4)
    private String residecity;

    @ColumnWidth(10)
    @ExcelProperty(value = "区/县", index = 5)
    private String residedist;

    @ColumnWidth(20)
    @ExcelProperty(value = "地址", index = 6)
    private String address;

    @ColumnWidth(12)
    @ExcelProperty(value = "公历生日", index = 7)
    private String birth;

    @ColumnWidth(12)
    @ExcelProperty(value = "农历生日", index = 8)
    private String yinlibirth;


    @ColumnWidth(12)
    @ExcelProperty(value = "是否闰月", index = 9)
    private String isLeapMonth;

}
controller代码

​ 前端页面上传一个name是file的文件

java 复制代码
    @ApiOperation("导入居士信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "weiqingview_backend_token", value = "token", required = true, dataType = "String", paramType = "header"),
            @ApiImplicitParam(name = "uniacid", value = "Unicid", required = true, dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(name = "file", value = "file", required = true, dataType = "MultipartFile", paramType = "query")
    })
    @PostMapping("/uploadExcel")
    public R uploadExcel(@RequestParam("file") MultipartFile file, @RequestParam Map<String, Object> params) {
        return mcMembersService.importExcel(file, params);
    }
service代码

​ 下面是接收controller传来的文件后,通过调用EasyExcel的read方法,直接进行导入操作

java 复制代码
    public R importExcel(MultipartFile file, Map<String, Object> params) {
        // 检查文件是否为空
        if (file.isEmpty()) {
            return R.error("没有检测到文件"); // 返回错误页面
        }

        try {

            // 执行导入操作
            EasyExcel.read(file.getInputStream(), ImportPmcMembersDTO.class, new ImportPmcMembersListener(this, params)).sheet().doRead();

            // 返回上传成功页面
            return R.ok("导入excel成功");

        } catch (IOException e) {
            e.printStackTrace();
            return R.error("导入excel失败");
        }
    }

​ 下面是service中基本的添加数据的操作方法,导入数据插库的时候也直接调用,就不写新的插库方法了

java 复制代码
public R pAdd(AddPmcMembersDTO addPmcMembersDTO, Map<String, Object> params) {
        McMembers mcMembers = new McMembers();
        BeanUtils.copyProperties(addPmcMembersDTO, mcMembers);
        mcMembers.setIsBeliever((byte) 1);

        Integer uniacid = Integer.parseInt(params.get("uniacid").toString());
        mcMembers.setUniacid(uniacid);

        if (this.save(mcMembers)) {
            return R.ok("添加成功");
        }

        return R.error("添加失败");
    }
listener代码

​ 上传的话需要定义一个listener,并继承AnalysisEventListener,这里的T类型就是上面定义的模型类的类型。

​ 如果是在listener中进行插库操作,那需要把service注入进来,但是在listener中不能用@Autowired,所以重写一个带参的构造方法,把注入好的service直接传进来使用即可,我下面将注入好的mcMembersService传递了进来,执行插库操作。下面的AddPmcMembersDTO是我另外定义的一个模型类,是用于界面上添加数据用的,这里直接转换后调用进行插库操作了。

​ 当然也可以在listener中先将excel中的数据都封装到List集合中,再统一将List中的数据插库也行。

java 复制代码
public class ImportPmcMembersListener extends AnalysisEventListener<ImportPmcMembersDTO> {

    private McMembersService mcMembersService;

    private Map<String, Object> params;
    
	//通过构造方法,得到注入好的mcMembersService
    public ImportPmcMembersListener(McMembersService mcMembersService, Map<String, Object> params) {
        this.mcMembersService = mcMembersService;
        this.params = params;
    }

    @Override
    public void invoke(ImportPmcMembersDTO data, AnalysisContext context) {
        // 处理读取到的每行数据,例如保存到数据库
        System.out.println("读取到一行数据: " + data.toString());
        // 这里可以添加保存到数据库的逻辑

        AddPmcMembersDTO addPmcMembersDTO = new AddPmcMembersDTO();
        addPmcMembersDTO.setMobile(data.getMobile());
        addPmcMembersDTO.setRealname(data.getRealname());
        addPmcMembersDTO.setGender((byte) (ObjectUtils.isEmpty(data.getGender()) ? 0 : data.getGender().equals("男") ? 1 : 2));

        addPmcMembersDTO.setAddress(data.getAddress());
        addPmcMembersDTO.setBirth(data.getBirth());
        addPmcMembersDTO.setYinlibirth(data.getYinlibirth());
        addPmcMembersDTO.setResidedist(data.getResidedist());
        addPmcMembersDTO.setResidecity(data.getResidecity());
        addPmcMembersDTO.setResideprovince(data.getResideprovince());
        addPmcMembersDTO.setIsLeapMonth((byte) (ObjectUtils.isEmpty(data.getIsLeapMonth()) ? 0 : data.getIsLeapMonth().equals("是") ? 1 : 0));

        // 进行插库操作
        mcMembersService.pAdd(addPmcMembersDTO, params);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 所有数据解析完毕后的回调
        System.out.println("所有数据解析完成");
    }

将一下excel数据进行导入操作

用Api工具测试了下,上传成功

查看数据库,数据也成功导入

整体感觉挺好用的,对于不同的数据进行导入的话,其实可以再封装成通用的listener,这样不用每一个功能导入都去定义一个listener,这个等后面有空再折腾吧。

结束

相关推荐
ManThink Technology2 分钟前
如何使用EBHelper 简化EdgeBus的代码编写?
java·前端·网络
invicinble6 分钟前
springboot的核心实现机制原理
java·spring boot·后端
人道领域14 分钟前
SSM框架从入门到入土(AOP面向切面编程)
java·开发语言
大模型玩家七七34 分钟前
梯度累积真的省显存吗?它换走的是什么成本
java·javascript·数据库·人工智能·深度学习
space621232739 分钟前
在SpringBoot项目中集成MongoDB
spring boot·后端·mongodb
CodeToGym1 小时前
【Java 办公自动化】Apache POI 入门:手把手教你实现 Excel 导入与导出
java·apache·excel
凡人叶枫1 小时前
C++中智能指针详解(Linux实战版)| 彻底解决内存泄漏,新手也能吃透
java·linux·c语言·开发语言·c++·嵌入式开发
JMchen1232 小时前
Android后台服务与网络保活:WorkManager的实战应用
android·java·网络·kotlin·php·android-studio
阔皮大师2 小时前
INote轻量文本编辑器
java·javascript·python·c#
小法师爱分享2 小时前
StickyNotes,简单便签超实用
java·python