springboot使用EasyExcel导入数据

news2024/11/16 6:41:53

springboot使用EasyExcel导入数据

1. 引入依赖

<!-- Easy Excel -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.2.1</version>
</dependency>

2. 建立对应实体类

假如,我想要读取的excel数据如下所示

image-20231213140048360.png

那么我的实体类为

@Getter
@Setter
@ToString
public class UserInfoForExcel {
    @ExcelProperty(value = "ID")
    private String userId;
    @ExcelProperty(value = "账号")
    private String account;
    @ExcelProperty(value = "邮箱")
    private String email;
    @ExcelProperty(value = "昵称")
    private String nickname;
    @ExcelProperty(value = "年龄")
    private Integer age;
    @ExcelProperty(value = "生日")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private Date birthday;
}

3. 读取代码

前端是以file的形式将excel表传过来的,springboot默认用MultipartFile类型接收,假设读取处理过程在service层

@Service
public class UserService {

    public void handleExcelImport(MultipartFile excelFile) throws IOException {
        InputStream inputStream = excelFile.getInputStream();
        List<UserInfoForExcel> userInfoForExcels = EasyExcel.read(inputStream)
            	.head(UserInfoForExcel.class)	// 行头类型匹配
                .sheet(0)				// sheet(0)为第一张表位置
                .headRowNumber(1)       // 行头所在行位置
                .doReadSync();			// 同步结果返回
        System.out.println(userInfoForExcels);
    }
}

4. 测试接口

@RestController
@RequestMapping("userinfo")
public class UserInfoController {

    @Autowired
    UserService userService;

    @PostMapping("import")
    public String handleExcelImport(MultipartFile file) throws IOException {
        userService.handleExcelImport(file);
        return "读取成功";
    }
}

5. 测试结果

image-20231213185235689.png

6. 补充

以上是最简单的读,且读的时候将所有数据读取到内存中,再进行处理,这样数据量一大,会导致占用内存过高甚至OOM,EasyExcel提供了自定义Listener,在读取时进行自定义操作,例如每次只读取5条数据,避免大量数据占用内存。

这只是举个简单的例子,事实上Listener还可以做很多复杂的操作,详情可以搜索EasyExcel官网,看看其API

7. 自定义监听器

/**
 * 自定义EasyExcel监听器
 */
public class UserInfoListener implements ReadListener<UserInfoForExcel> {
    // 设置缓存数据量
    private static final int BATCH_COUNT = 5;

    // 缓存数据List
    private List<UserInfoForExcel> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

    /**
     * 每条数据都会调用该方法
     * @param userInfoForExcel 读取的一行数据
     * @param analysisContext 上下文对象,包含excel表的很多基本信息
     */
    @Override
    public void invoke(UserInfoForExcel userInfoForExcel, AnalysisContext analysisContext) {
        cachedDataList.add(userInfoForExcel);
        if (cachedDataList.size()>=BATCH_COUNT){
            // 达到预定数据量,进行插入数据库操作
            // …… todo
            // 然后清空缓存数据
            cachedDataList.clear();
        }
    }

    /**
     * 所有数据执行完invoke,会调用该方法
     * 由于最后的数据可能没有达到缓存定义的BATCH_COUNT,导致最后缓存中的数据没有进行插入数据库操作,所以需要在此进行数据插入
     * @param analysisContext 上下文对象,包含excel表的很多基本信息
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        // 缓存List中剩余的数据进行插入数据库操作
        // …… todo
    }
}

有一点需要注意的是,如果在插入数据库操作时使用spring管理的dao,不能将Listener对象交由spring管理(即是贪图方便在该Listener上添加@Component等注释),而应该将操作数据库的dao通过Listener的有参构造器传进来。EasyExcel官网有特别提醒

8. 使用自定义的监听器

创建完自定义的监听器后,在读取时注册该监听器,并且读时不需要使用doReadSync,改为doRead即可

@Service
public class UserService {

    public void handleExcelImport(MultipartFile excelFile) throws IOException {
        InputStream inputStream = excelFile.getInputStream();
        EasyExcel.read(inputStream).head(UserInfoForExcel.class)
                .sheet(0)
                .registerReadListener(new UserInfoListener()) // 注册自定义监听器
                .headRowNumber(1)       //行头所在行位置
                .doRead();
    }

}

至此,EasyExcel的简单读描述完毕。

事实上EasyExcel的监听器还能做很多有用的事情,强烈建议到官网看文档,基本能解决95%的需求

官网地址:https://easyexcel.opensource.alibaba.com/

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

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

相关文章

多线程JUC 第2季 CAS的作用介绍

一 CAS作用介绍 1.1 CAS作用 CAS有3个操作数&#xff0c;位置内存值V&#xff0c;旧的预期值A&#xff0c;要修改的更新值B&#xff0c;如果内存值V和预期值相同则&#xff0c;内存值改为B&#xff0c;否则什么都不做。当它重来重试的这种行为称为-自旋。 CAS是一条cpu的原…

为什么越来越多的人从事软件测试行业?

1.市场需求增加&#xff1a;随着数字化转型和互联网的普及&#xff0c;各行各业都需要高质量、稳定可靠的软件来支持其业务运作。因此&#xff0c;对软件测试人员的需求也随之增加。同时&#xff0c;新兴技术的发展&#xff0c;如物联网、大数据、区块链、人工智能等&#xff0…

git学习笔记03(小滴课堂)

详解分支的基本操作 创建分支&#xff1a; 查看分支&#xff1a; 切换分支&#xff1a; git branch 中星号是当前分支。 idea中也更新了。 提交上去。 我们新建个分支&#xff1a; 我们新建分支是复制当前分支&#xff0c;而不是直接复制的主分支。 我们切换回主分支&#xf…

Bounding boxes augmentation for object detection

Different annotations formats Bounding boxes are rectangles that mark objects on an image. There are multiple formats of bounding boxes annotations. Each format uses its specific representation of bouning boxes coordinates 每种格式都使用其特定的边界框坐标…

51单片机控制1602LCD显示屏输出两行文字一

51单片机控制1602LCD显示屏输出两行文字一 1.概述 这篇文章介绍1602型号显示屏的基础知识&#xff0c;以及使用单片机控制它输出两行内容。 2.1602基础知识 1602 液晶显示模块是一种通用的工业液晶显示模块&#xff0c;专门用来显示字母、数字、符号等的点阵型液晶显示模块…

C++智能指针介绍

引言 为了充分利用RAII思想&#xff0c;C 11开始引入了智能指针&#xff0c;本文介绍RAII以及三种智能指针&#xff1a; std::unique_ptrstd::shared_ptrstd::weak_ptr 除此之外&#xff0c;本文还会介绍智能指针的常用创建方法&#xff1a; std::make_uniquestd::make_sha…

微信小程序:用map()将对象数组中的某一项组合成新数组

使用分析 使用map()方法来遍历 info 数组中的每个元素&#xff0c;并整合每一个对象中的某一项进行新数组的重组 效果展示 这里是查询对象数组中的全部name值 原始数据 提取出name的数组 核心代码 var infos items.map(item > item.name); 完整代码&#xff08;用微信小程…

iOS按钮控件UIButton使用

1.在故事板中添加按钮控件,步聚如下: 同时按钮Shift+Commad+L在出现在控件库中选择Button并拖入View Controller Scene中 将控件与变量btnSelect关联 关联后空心变实心 如何关联?直接到属性窗口拖按钮变量到控件上,出现一条线,然后松开,这样就关联成功了 关联成功后属性窗口…

Redis HyperLogLog 数据结构模型统计

HyperLogLog HyperLogLog 不是一种新的数据结构 &#xff0c; 本质上是字符串类型。 是一种基数算法。 通过 HyperLogLog 可以节省内存空间&#xff0c;并完成独立总数的统计。 HyperLogLog 数据结构可用于仅使用少量恒定内存来计算集合中的唯一元素&#xff0c;具体而言&…

Web开发:VS2022列表导出CSV中文乱码问题(已解决)

目录 一、问题重现 二、解决方案 1.新建一个EXCEL文档 2.点击数据-点击导入&#xff08;生成的文件&#xff09;-设置中文格式 一、问题重现 使用VS2022 DEBUG导出列表时&#xff0c;打开CSV文件发现中文乱码 二、解决方案 1.新建一个EXCEL文档 2.点击数据-点击导入&…

新手选电视盒子什么牌子好?内行分享最新电视盒子排名

新手们在面对众多品牌和机型时难免不知道如何挑选电视盒子&#xff0c;电视盒子的品质良莠不齐&#xff0c;究竟电视盒子什么牌子好&#xff1f;我身为从业人员&#xff0c;身边朋友在挑选电视盒子时都会咨询我的意见&#xff0c;我特意整理了业内最新发布的热门电视盒子排名TO…

选择销售技巧培训机构注意事项

选择销售技巧培训机构注意事项 随着市场竞争的日益激烈&#xff0c;销售技巧对于企业的成功至关重要。为了提升销售团队的技能&#xff0c;许多企业选择投资于销售技巧培训机构。然而&#xff0c;在选择培训机构时&#xff0c;有几个关键因素需要考虑。本文将介绍选择销售技巧…

亚马逊云科技re_Invent 2023产品体验:亚马逊云科技产品应用实践 王炸产品Amazon Q,你的AI助手

本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 亚马逊云科技开发者社区, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道 意料之中 2023年9月25日&#xff0c;亚马逊宣布与 Anthropic 正式展开战略合作&#x…

详解接口测试

目录 什么是接口&#xff1f; 接口协议的类型 接口测试是什么 HTTP接口的测试用例设计 HTTP接口的测试方法 什么是接口&#xff1f; 在面向对象编程中&#xff0c;接口是一个抽象的概念&#xff0c;用于定义类应该具有的方法和属性。一个类可以实现一个或多个接口&#xf…

如何解决掉你的u盘装不进去文件大小过大的文件

目录 前言1.解决方案2.原因2.1查看自己u盘格式2.2不同格式2.3分配单元大小作用 &#x1f44d; 点赞&#xff0c;你的认可是我创作的动力&#xff01; ⭐️ 收藏&#xff0c;你的青睐是我努力的方向&#xff01; ✏️ 评论&#xff0c;你的意见是我进步的财富&#xff01; 前言…

Ubuntu环境下使用GDB调试C语言项目

1. 安装gdb //终端输入 sudo apt-get install gdb 2. 启动gdb gdb GDB常用命令大全&#xff0c;参考此篇博客 使用GDB调试C项目中的makefile 1.在内核配置中启用调试信息&#xff1a; 在内核配置中&#xff0c;确保启用了调试信息。可以通过以下步骤来配置内核&#xff1…

uniapp 蓝牙小程序-兼容安卓和iOS

withTimeout方法可以在搜寻设备时等待指定的秒数&#xff0c;如果30秒内未搜索到则取消搜索 /*** 超时控制函数* param {Promise} promise 回调函数* param {number} timeout 超时时间, 默认10s*/ export function withTimeout(promise, timeout 10000) {let timeoutEvent …

FFmpeg的AVFilter框架总成AVFilter-AVFilterContext

毫无疑问&#xff0c;还是和前面的一样一个context和一个包含有回调函数指针的插件结构体&#xff0c;想要实现自己的插件&#xff0c;主要实现里面的回调函数就可以了&#xff0c;当然&#xff0c;AVFilter比其它模块稍微复杂一点还要牵扯到其它一些辅助模块&#xff0c;在其它…

华为OD试题六(数据最节约的备份方法、TLV解码)

1. 数据最节约的备份方法 题目描述&#xff1a; 有若干个文件&#xff0c;使用刻录光盘的方式进行备份&#xff0c;假设每张光盘的容量是500MB&#xff0c;求 使用光盘最少的文件分布方式 所有文件的大小都是整数的MB&#xff0c;且不超过500MB&#xff1b;文件不能分割、分卷…

elementui select中添加新增标签

<el-select v-model"ruleForm.eventType" :placeholder"请选择事件类型&#xff0c;可手动添加" ref"template" clearable visible-change"(v) > visibleChange(v, template)"><el-option v-for"item in eventTypeOp…