最新要闻
- 全球播报:玩家最喜欢的复古游戏TOP5:《俄罗斯方块》排第二
- 环球快资讯:程序员也危险了!GPT-4十秒即可生成一个网站
- 焦点消息!ChatGPT升级为GPT-4 会看图懂幽默 细思极恐
- 充电慢、续航差、反馈无门!bZ3X首批车主公开致信广汽丰田董事长
- 不接董事长电话1次罚1万元 公司回应:合不合法你说了不算
- 【热闻】保时捷去年净赚499亿元:国人给力 中国连续八年为最大市场
- 打工几年就能买北京四合院?新剧《心想事成》开播引热议
- 男子辞职摆摊拍照 1月内激增14家同行 建议大家好好上班
- 快资讯丨Meta宣布再裁员上万人 连HR都裁了!扎克伯格给出理由
- 【世界新视野】韩国SBS电视台回应剪辑杨紫琼感言:未刻意针对女性
- 焦点报道:3月15日热股前瞻:7股突发利好
- 【天天热闻】315来临!消费者起诉东方甄选 官方:我们也被供应商骗了
- 环球即时看!网文连载十余年被网友举报 1万多章还没结尾:作者回应了
- 每日快看:2022年新能源汽车投诉量增长62.84%:行驶中突然熄火、漏油成热点
- 世界信息:高速免费!2023年清明节放假通知来了:1天假 不调休
- 每日看点!苹果为何不做电视?真实原因揭开
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
自从用了 EasyExcel,导入导出 Excel 更简单了!
作者:风雨兼程 来源:jianshu.com/p/8f3defdc76d4
EasyExcel
在做excel导入导出的时候,发现项目中封装的工具类及其难用,于是去gitHub上找了一些相关的框架,最终选定了EasyExcel。之前早有听闻该框架,但是一直没有去了解,这次借此学习一波,提高以后的工作效率。
实际使用中,发现是真的很easy,大部分api通过名称就能知道大致意思,这点做的很nice。参考文档,大部分场景的需求基本都能够满足。
(相关资料图)
GitHub上的官方说明
快速开始
maven仓库地址
com.alibaba easyexcel 2.1.2
推荐一个开源免费的 Spring Boot 最全教程:
https://github.com/javastacks/spring-boot-best-practice
导入
如下图excel表格:
建立导入对应实体类
@Datapublic class ReqCustomerDailyImport { /** * 客户名称 */ @ExcelProperty(index = 0) private String customerName; /** * MIS编码 */ @ExcelProperty(index = 1) private String misCode; /** * 月度滚动额 */ @ExcelProperty(index = 3) private BigDecimal monthlyQuota; /** * 最新应收账款余额 */ @ExcelProperty(index = 4) private BigDecimal accountReceivableQuota; /** * 本月利率(年化) */ @ExcelProperty(index = 5) private BigDecimal dailyInterestRate;}
Controller代码
@PostMapping("/import")public void importCustomerDaily(@RequestParam MultipartFile file) throws IOException { InputStream inputStream = file.getInputStream(); List reqCustomerDailyImports = EasyExcel.read(inputStream) .head(ReqCustomerDailyImport.class) // 设置sheet,默认读取第一个 .sheet() // 设置标题所在行数 .headRowNumber(2) .doReadSync();}
运行结果
可以看出只需要在实体对象使用@ExcelProperty注解,读取时指定该class,即可读取,并且自动过滤了空行,对于excel的读取及其简单。不过此时发现一个问题,这样我如果要校验字段该怎么办?要将字段类型转换成另外一个类型呢?
不必担心,我们可以想到的问题,作者肯定也考虑到了,下面来一个Demo
代码如下
List reqCustomerDailyImports = EasyExcel.read(inputStream) // 这个转换是成全局的, 所有java为string,excel为string的都会用这个转换器。 // 如果就想单个字段使用请使用@ExcelProperty 指定converter .registerConverter(new StringConverter()) // 注册监听器,可以在这里校验字段 .registerReadListener(new CustomerDailyImportListener()) .head(ReqCustomerDailyImport.class) .sheet() .headRowNumber(2) .doReadSync();}
监听器
public class CustomerDailyImportListener extends AnalysisEventListener { List misCodes = Lists.newArrayList(); /** * 每解析一行,回调该方法 * @param data * @param context */ @Override public void invoke(Object data, AnalysisContext context) { String misCode = ((ReqCustomerDailyImport) data).getMisCode(); if (StringUtils.isEmpty(misCode)) { throw new RuntimeException(String.format("第%s行MIS编码为空,请核实", context.readRowHolder().getRowIndex() + 1)); } if (misCodes.contains(misCodes)) { throw new RuntimeException(String.format("第%s行MIS编码已重复,请核实", context.readRowHolder().getRowIndex() + 1)); } else { misCodes.add(misCode); } } /** * 出现异常回调 * @param exception * @param context * @throws Exception */ @Override public void onException(Exception exception, AnalysisContext context) throws Exception { // ExcelDataConvertException:当数据转换异常的时候,会抛出该异常,此处可以得知第几行,第几列的数据 if (exception instanceof ExcelDataConvertException) { Integer columnIndex = ((ExcelDataConvertException) exception).getColumnIndex() + 1; Integer rowIndex = ((ExcelDataConvertException) exception).getRowIndex() + 1; String message = "第" + rowIndex + "行,第" + columnIndex + "列" + "数据格式有误,请核实"; throw new RuntimeException(message); } else if (exception instanceof RuntimeException) { throw exception; } else { super.onException(exception, context); } } /** * 解析完全部回调 * @param context */ @Override public void doAfterAllAnalysed(AnalysisContext context) { misCodes.clear(); }}
转换器
public class StringConverter implements Converter { @Override public Class supportJavaTypeKey() { return String.class; } @Override public CellDataTypeEnum supportExcelTypeKey() { return CellDataTypeEnum.STRING; } /** * 将excel对象转成Java对象,这里读的时候会调用 * * @param cellData NotNull * @param contentProperty Nullable * @param globalConfiguration NotNull * @return */ @Override public String convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { return "自定义:" + cellData.getStringValue(); } /** * 将Java对象转成String对象,写出的时候调用 * * @param value * @param contentProperty * @param globalConfiguration * @return */ @Override public CellData convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { return new CellData(value); }}
可以看出注册了一个监听器:CustomerDailyImportListener,还注册了一个转换器:StringConverter。流程为:框架读取一行数据,先执行转换器,当一行数据转换完成,执行监听器的回调方法,如果转换的过程中,出现转换异常,也会回调监听器中的onException方法。因此,可以在监听器中校验数据,在转换器中转换数据类型或者格式。
运行结果
修改一下表格,测试校验是否生效
再次导入,查看运行结果
导入相关常用API
注解
ExcelProperty
指定当前字段对应excel中的那一列。可以根据名字或者Index去匹配。当然也可以不写,默认第一个字段就是index=0,以此类推。千万注意,要么全部不写,要么全部用index,要么全部用名字去匹配。千万别三个混着用,除非你非常了解源代码中三个混着用怎么去排序的。ExcelIgnore
默认所有字段都会和excel去匹配,加了这个注解会忽略该字段。DateTimeFormat
日期转换,用String去接收excel日期格式的数据会调用这个注解。里面的value参照java.text.SimpleDateFormat。NumberFormat
数字转换,用String去接收excel数字格式的数据会调用这个注解。里面的value参照java.text.DecimalFormat。
EasyExcel相关参数
readListener
监听器,在读取数据的过程中会不断的调用监听器。converter
转换器,默认加载了很多转换器。也可以自定义,如果使用的是registerConverter,那么该转换器是全局的,如果要对单个字段生效,可以在ExcelProperty注解的converter指定转换器。headRowNumber
需要读的表格有几行头数据。默认有一行头,也就是认为第二行开始起为数据。- head 与clazz二选一。读取文件头对应的列表,会根据列表匹配数据,建议使用class。
autoTrim
字符串、表头等数据自动trim。sheetNo
需要读取Sheet的编码,建议使用这个来指定读取哪个Sheet。sheetName
根据名字去匹配Sheet,excel 2003不支持根据名字去匹配。
导出
建立导出对应实体类
@Data@Builderpublic class RespCustomerDailyImport { @ExcelProperty("客户编码") private String customerName; @ExcelProperty("MIS编码") private String misCode; @ExcelProperty("月度滚动额") private BigDecimal monthlyQuota; @ExcelProperty("最新应收账款余额") private BigDecimal accountReceivableQuota; @NumberFormat("#.##%") @ExcelProperty("本月利率(年化)") private BigDecimal dailyInterestRate;}
Controller代码
@GetMapping("/export")public void export(HttpServletResponse response) throws IOException { // 生成数据 List respCustomerDailyImports = Lists.newArrayList(); for (int i = 0; i < 50; i++) { RespCustomerDailyImport respCustomerDailyImport = RespCustomerDailyImport.builder() .misCode(String.valueOf(i)) .customerName("customerName" + i) .monthlyQuota(new BigDecimal(String.valueOf(i))) .accountReceivableQuota(new BigDecimal(String.valueOf(i))) .dailyInterestRate(new BigDecimal(String.valueOf(i))).build(); respCustomerDailyImports.add(respCustomerDailyImport); } response.setContentType("application/vnd.ms-excel"); response.setCharacterEncoding("utf-8"); // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系 String fileName = URLEncoder.encode("导出", "UTF-8"); response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); EasyExcel.write(response.getOutputStream(), RespCustomerDailyImport.class) .sheet("sheet0") // 设置字段宽度为自动调整,不太精确 .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) .doWrite(respCustomerDailyImports);}
导出效果
导出相关常用API
注解
ExcelProperty
指定写到第几列,默认根据成员变量排序。value指定写入的名称,默认成员变量的名字。ExcelIgnore
默认所有字段都会写入excel,这个注解会忽略这个字段。DateTimeFormat
日期转换,将Date写到excel会调用这个注解。里面的value参照java.text.SimpleDateFormat。NumberFormat
数字转换,用Number写excel会调用这个注解。里面的value参照java.text.DecimalFormat。
EasyExcel相关参数
needHead
监听器是否导出头。useDefaultStyle
写的时候是否是使用默认头。- head 与clazz二选一。写入文件的头列表,建议使用class。
autoTrim
字符串、表头等数据自动trim。sheetNo
需要写入的编码。默认0。sheetName
需要些的Sheet名称,默认同sheetNo。
总结
可以看出不管是excel的读取还是写入,都是一个注解加上一行代码完成,可以让我们少些很多解析的代码,极大减少了重复的工作量。当然这两个例子使用了最简单的方式,EasyExcel还支持更多场景,例如读,可以读多个sheet,也可以解析一行数据或者多行数据做一次入库操作;写的话,支持复杂头,指定列写入,重复多次写入,多个sheet写入,根据模板写入等等。
近期热文推荐:
1.1,000+ 道 Java面试题及答案整理(2022最新版)
2.劲爆!Java 协程要来了。。。
3.Spring Boot 2.x 教程,太全了!
4.别再写满屏的爆爆爆炸类了,试试装饰器模式,这才是优雅的方式!!
5.《Java开发手册(嵩山版)》最新发布,速速下载!
觉得不错,别忘了随手点赞+转发哦!
关键词:
-
自从用了 EasyExcel,导入导出 Excel 更简单了!
作者:风雨兼程来源:jianshu com p 8f3defdc76d4EasyExcel在做excel导入导出的时候,发现项目中封装...
来源: 自从用了 EasyExcel,导入导出 Excel 更简单了!
浅谈var,let,const
今日最新!Maven学习笔记3:在idea中使用Maven
全球播报:玩家最喜欢的复古游戏TOP5:《俄罗斯方块》排第二
环球快资讯:程序员也危险了!GPT-4十秒即可生成一个网站
焦点消息!ChatGPT升级为GPT-4 会看图懂幽默 细思极恐
充电慢、续航差、反馈无门!bZ3X首批车主公开致信广汽丰田董事长
不接董事长电话1次罚1万元 公司回应:合不合法你说了不算
项目构建node-sass源码报错 SyntaxError:Unexpectedtoken"?"
前端设计模式——命令模式
【热闻】保时捷去年净赚499亿元:国人给力 中国连续八年为最大市场
打工几年就能买北京四合院?新剧《心想事成》开播引热议
男子辞职摆摊拍照 1月内激增14家同行 建议大家好好上班
快资讯丨Meta宣布再裁员上万人 连HR都裁了!扎克伯格给出理由
【世界新视野】韩国SBS电视台回应剪辑杨紫琼感言:未刻意针对女性
焦点报道:3月15日热股前瞻:7股突发利好
今日报丨建议收藏chatGPT说的Ubuntu下常用网络命令合集
【天天热闻】315来临!消费者起诉东方甄选 官方:我们也被供应商骗了
环球即时看!网文连载十余年被网友举报 1万多章还没结尾:作者回应了
每日快看:2022年新能源汽车投诉量增长62.84%:行驶中突然熄火、漏油成热点
世界信息:高速免费!2023年清明节放假通知来了:1天假 不调休
每日看点!苹果为何不做电视?真实原因揭开
2023年安卓之光!小米13 Ultra曝光:支持可变光圈
读Java性能权威指南(第2版)笔记17_垃圾回收D
刚刚,拜登最新表态!两大重磅降临,欧美多头集体沸腾!危机一闪而过?这家巨头突然"捅刀"
拒绝卡脖子 我国掌握量子计算核心技术:低温接近绝对零度
4家汽车公司明确不打价格战 定位豪华品牌:特斯拉比亚迪看笑
如何用好免费的chatGPT
全球观焦点:算法模板总结 1
【独家焦点】预算3000元 找老鸟装了台12代U ITX小主机:这配置你看如何?
天天视讯!AMD最强核显跑分逆天!竟然逼平GTX 1650、RX 480
热点在线丨女演员被困五星级酒店厕所超3小时!酒店回应:属于特例
头条焦点:《速度与激情10》新海报发布:范迪塞尔携众家人再度狂飙
深圳带奶茶跑腿回港火了:一趟就能赚数百元
丙二醇的功效_丙二醇的功效与作用
今日热讯:《consul 简易上手指南》
每日简讯:《碟中谍7:致命清算》首张海报:阿汤哥悬崖飞车冲上云霄!
【快播报】CPU突然变慢、Adobe异常崩溃:NVIDIA终于出手
【天天播资讯】动物园棕熊能懂人话 被质疑是人假扮:回应确实是真熊
第三十一天 面向对象编程的基础
每日观点:c++11多线程入门<学习记录>
当前通讯!day03-分析SpringBoot底层机制
关于AWS-S3-Bucket-Console-Web控制页面上的Creation date与命令行-API方式如何获取到真正的CreationDate
天天速看:深圳居住登记信息服务_深圳市居住登记服务平台
焦点播报:游客为拍照不听劝阻喂狐狸吃面包 无视劝阻!会危害动物
Vue——mergeOptions【四】
播报:院线票房止步9000万:《中国乒乓》官宣3月17日登陆线上平台
华硕发布新款迷你主机:高配i7-13700H、配备雷电4
环球热点评!.NET中比肩System.Text.Json序列化反序列化组件MessagePack
路飞-项目上线
今亮点!分布式架构-可观测性-事件日志
【全球热闻】教你用Python画个可爱的皮卡丘!(附完整源码)
每日资讯:Educational Codeforces Round 123 (Rated for Div. 2)
网传梅西要来 黄牛提前卖票!阿根廷国家足球队辟谣“中国行”
【新要闻】315白皮书:价格刺客成消费者年度最关注现象、购物平台为年度被投诉最多行业
环球时讯:西安机场为首次坐飞机旅客安排指引服务:佩戴专属手环 全程有人引导
速度10倍于普通U盘!联想小新原厂颗粒固态U盘发售:USB 3.2双口
12万买C6?想多了!雪铁龙都是套路:想提车先交29万
记录--你不知道的forEach函数
智能勘探 | AIRIOT智慧油田管理解决方案
环球聚焦:NOI春季测试游记
微贺卡
《黑暗荣耀2》热播!演员透露拍摄细节:剧里的蛇是真蛇
82版《西游记》编剧戴英禄逝世 六小龄童发文悼念
当前关注:理想汽车L8首批车主调研:300名中车主开BBA的最多
环球播报:国产车崛起 豪华车丝毫不怂:市场份额继续增 有钱人多
最新资讯:努比亚Z50 Ultra首销卖爆:获京东/天猫平台销量销售额冠军
报道:第一章 软件工程概述
每日看点!centos7.9离线升级openssl和openssh9.2
python语言基础
每日焦点!Mysql数据库未添加索引引发的生产事故
对极几何的理解和原理推导
卡塔尔世界杯官方授权:富光1.5L顿顿桶29元发车
焦点精选!零碳排放!我国首款双源智能重卡成功下线:自带大辫子
视焦点讯!全球打广告最划算的一块屏?登上纽约时代广场屏幕只需40美元
《狂飙》后 张译宣传新剧《他是谁》:今晚优酷、央视开播
获赔近100万 报废奔驰翻新再销售被判退1赔3 网友:C级秒变大S
每日快讯!10Wqps 超高并发 API网关 架构演进之路
Egg.js 学习笔记01
世界快看:git提交规范
【全球速看料】早起、冥想、阅读、写作、运动
焦点讯息:观察者模式——学习笔记
天天最新:dnf游戏闪退怎么解决方法_dnf游戏闪退
停车场闸机防骗能力太弱鸡:博主实测一部手机、一张纸均可通行
曾模仿东方甄选直播带货 好未来旗下学而思大规模重启线下招生
白皮书:购物平台为2022年度消费者投诉最多的行业
天天播报:315前海鲜加工厂的狠活被曝光:硼砂泡出黄金鲍 系明令禁止食品添加剂
世界焦点!两只售价3899元:华硕ROG推出魔方幻路由器月曜白限定版
卷起来!!!看了这篇文章我才知道MySQL事务&MVCC到底是啥?
蓝牙Mesh简介(一)设备标识:UUID和Mesh地址
开源免费:分享powershell读写k8s的etcd的脚本库
环球速递!冲击全球的“硅谷银行破产”到底咋回事?会不会引爆危机?
视点!国产AYA新掌机Ayaneo 2 IGN9分好评:价格贵 但很好用!
【聚看点】央视3·15晚会官宣明晚举办 这次谁会被曝光?
世界最资讯丨配置大升级!新款比亚迪唐DM-i/汉EV冰川蓝实车亮相:绝对吸睛
上海测试9辆自动驾驶清扫车 可替代25名环卫工人
干货来袭!3天0基础Python实战项目快速学会人工智能必学数学基础全套(含源码)(第3天)概率分析篇:条件概率、全概率与贝叶斯公式
韩国电视台剪掉杨紫琼获奖感言:鼓励女性部分没了
腾讯会议重大调整!取消免费300人不限时会议使用
世界看热讯:斥资10亿美元!NASA将开发太空拖船:实现国际空间站受控坠落