EasyExcel简单使用

news2024/11/13 9:29:24

EasyExcel简单使用

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

导入Maven依赖:
<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则是内容所在的列的位置

@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代码
    @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文件供下载

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);
        }

    }

image-20240511105026375

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

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

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

@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的文件

    @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方法,直接进行导入操作

    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中基本的添加数据的操作方法,导入数据插库的时候也直接调用,就不写新的插库方法了

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中的数据插库也行。

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数据进行导入操作

image-20240511112040930

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

image-20240511112220656

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

image-20240511112302526

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

结束

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1666842.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

图和网络笔记

文章目录 1. 图(节点边) 1. 图(节点边) 一个图可以由节点和边组成&#xff0c;假设我们有一个节点notes &#xff1a;n4,边edges&#xff1a;m5的有向图&#xff0c;表示如下 通过以上电路图可以得到关联矩阵(incident matrix),我们定义边&#xff0c;开始端用-1表示&#x…

Elasticsearch查看集群信息,设置ES密码,Kibana部署

Elasticsearch查看集群信息&#xff0c;设置ES密码&#xff0c;Kibana部署 查看集群信息查看节点信息查看集群健康状态查看分片信息查看其他集群信息 Kibana部署安装设置ES密码 查看集群信息 查看节点信息 curl http://127.0.0.1:9200/_cat/nodes?v 参数说明&#xff1a; ip…

基于大模型的idea提炼:围绕论文和引用提炼idea之ResearchAgent

前言 对本博客比较熟悉的朋友知道&#xff0c;我司论文项目组正在基于大模型做论文的审稿(含CS英文论文审稿、和金融中文论文审稿)、翻译&#xff0c;且除了审稿翻译之外&#xff0c;我们还将继续做润色/修订、idea提炼(包含论文检索)&#xff0c;是一个大的系统&#xff0c;包…

星辰考古:TiDB v1.0 再回首

“ 1.0 版本只是个开始&#xff0c;是新的起点&#xff0c;愿我们一路相扶&#xff0c;不负远途。 前言 TiDB 是 PingCAP 公司自主设计、研发的开源分布式关系型数据库。 近日&#xff0c;TiDB v8.0.0 DMR 发布&#xff0c;详细发版说明戳这里&#xff1a; https://docs.pingca…

【C/C++】C/C++ KTV点歌系统设计与实现(源码+数据+报告)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

3588 pwm android12 的操作

问题&#xff1a; 客户需要在android12 的界面上操作板卡上的 PWM 蜂鸣器设备。 过程&#xff1a; 1 了解一下 3588 android12 源码的 关于PWM 的驱动。 设备树找不到 pwm 但是&#xff0c; 还不知道&#xff0c;android12 最终包含的 设备树是哪个&#xff0c;但是经过我的…

MyCat实现分库分表

两个集群 两个库 两个表 搭建数据库服务使用docker启动两个mysql 3506 3507连接MyCat创建两个数据源连接MyCat创建集群 mycat创建逻辑库MyCat创建全局表广播表创建分片表mycat逻辑库MyCat插入数据mycat查看数据物理库3506查看数据物理库3507查看数据 ER表创建ER表mycat插入数据…

蓝桥杯练习系统(算法训练)ALGO-946 Q神的足球赛

资源限制 内存限制&#xff1a;256.0MB C/C时间限制&#xff1a;1.0s Java时间限制&#xff1a;3.0s Python时间限制&#xff1a;5.0s 问题描述 足球赛上&#xff0c;只见Q神如闪电般的速度带球时而左&#xff0c;时而右&#xff0c;时而前&#xff0c;时而后&#xff…

HDFS HA 修改nameservice

本例中修改将原来的hdfs-ha 修改为 hdfs-ns 停止HDFS, 防止新的业务操作 等待停止结束 KDE中需要调整的配置项如下图所示 a.搜索栏找到fs.defaultFS&#xff0c;将hdfs://hdfs-ha改为hdfs://hdfs-ns b.搜索栏找到dfs.nameservices&#xff0c;将hdfs-ha改为hdfs-ns c.搜索栏找…

HBuilder报错--openssl-legacy-provider is not allowed in NODE_OPTIONS解决方法

目录 一、问题描述二、解决方法 一、问题描述 HBuilder编译时报错&#xff1a;–openssl-legacy-provider is not allowed in NODE_OPTIONS 二、解决方法 将 windows 环境变量 NODE_OPTIONS 的值设置为空&#xff0c;由&#xff1a; 改为&#xff1a;

并发-判断线程对象是否处于活动状态 - isAlive

t.isAlive() 测试线程t是否处于活动状态&#xff0c;只要线程启动并且没有终止&#xff0c;方法返回值就是truestart()之前&#xff0c;线程不处于活动状态&#xff0c;之后就处于活动状态示例&#xff1a;运行结果&#xff1a;但是事情并没有这么简单&#xff0c;先来看一下以…

【每日刷题】Day37

【每日刷题】Day37 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 2391. 收集垃圾的最少总时间 - 力扣&#xff08;LeetCode&#xff09; 2. 1614. 括号的最大嵌套深度…

软件库V1.5版本iApp源码V3

软件库V1.5版本iApp源码V3 配置教程在【mian.iyu】的【载入事件】 更新内容&#xff1a; 1、分类对接蓝奏&#xff08;免费&#xff0c;付费&#xff0c;会员&#xff0c;广告&#xff09;&#xff0c;支持蓝奏文件描述设置为简介&#xff08;改动&#xff1a;首页.iyu&#…

【算法】二叉树中的dfs

快乐的流畅&#xff1a;个人主页 个人专栏&#xff1a;《算法神殿》《数据结构世界》《进击的C》 远方有一堆篝火&#xff0c;在为久候之人燃烧&#xff01; 文章目录 引言一、计算布尔二叉树的值二、求根节点到叶节点数字之和三、二叉树剪枝四、验证搜索二叉树五、二叉搜索树中…

该从哪些方面提升系统的吞吐量?

更多大厂面试内容可见 -> http://11come.cn 该从哪些方面提升系统的吞吐量&#xff1f; 我们平时自己做的项目一般没有用户量&#xff0c;都是练手项目&#xff0c;所以并不会在吞吐量上做出很多的优化&#xff0c;但是这样的话&#xff0c;又会导致项目和其他人相比并没有…

mysql设置远程访问权限,允许其他IP访问

文章目录 更改mysql配置文件登录mysql 更改mysql配置文件 查找.ini或者.cnf文件 更改bind-address为0.0.0.0 [mysqld] character-set-serverutf8mb4 bind-address0.0.0.0 default-storage-engineINNODB [mysql] default-character-setutf8mb4 [client] default-character-s…

ppt保存文件奇怪问题

我发现ppt中的形状保存成jpg,png和pdf时&#xff0c;格式不一样 比如 当右键单击时&#xff0c;然后选择另存为图片 png格式 jpg格式 pdf格式 感觉还是很奇怪&#xff0c;就pdf的格式比较靠谱一点

Java---类和对象第一节

目录 1.面向对象初步认识 1.1什么是面向对象 1.2面向对象和面向过程的区别 2.类的定义和使用 2.1简单认识类 2.2类的定义格式 2.3类的实例化 2.4类和对象的说明 3.this关键字 3.1访问本类成员变量 3.2调用构造方法初始化成员变量 3.3this引用的特性 4.对象的构造以…

国内有哪些知名的网络安全厂商?

首先就是360&#xff0c;这个我相信大家并不陌生了吧&#xff0c;你的电脑装过360么&#xff1f; 360在个人终端服务那是妥妥的扛把子&#xff0c;但是在企业服务里虽然有他们的身影却略显不足。 第二个就是深信服&#xff0c;网络安全的老牌大佬&#xff0c;业务覆盖了全球5…

什么是XXE漏洞,日常如何做好web安全,避免漏洞威胁

随着网络技术的不断发展&#xff0c;网站安全问题日益受到人们的关注。当前随着技术发展&#xff0c;网站存在一些常见的可能被攻击者利用的漏洞&#xff0c;而在众多网站安全漏洞中&#xff0c;XXE&#xff08;XML External Entity&#xff09;漏洞是一个不容忽视的问题。今天…