网站首页 > 博客文章 正文
一、开始整合
(1)引入 Maven 依赖
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.22</version>
</dependency>
<!-- easy excel -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
(2)创建测试对象类和准备测试 Excel 文件
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.alibaba.excel.annotation.format.NumberFormat;
import com.alibaba.excel.enums.BooleanEnum;
import lombok.Data;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 测试导入DTO
*/
@Data
public class DemoDto {
/** excel 的行号 */
@ExcelIgnore
private Long lineNum;
/** 第一列:序号 */
@ExcelProperty(value = "序号", index = 0)
private Long indexNo;
/** 第二列:名称 */
@ExcelProperty(value = "名称", index = 1)
private String name;
/** 第三列:分数 */
@ExcelProperty(value = "分数", index = 2)
private Double score;
/** 第四列:学费(小数转成字符串格式化 - 正确识别) */
@ExcelProperty(value = "学费", index = 3)
@NumberFormat("#.####")
private String money;
/** 第五列:入学如期 */
@ExcelProperty(value = "入学如期", index = 4)
@DateTimeFormat(value = "yyyy-MM-dd")
private LocalDate entryDate;
/** 第六列:缴费时间 */
@ExcelProperty(value = "缴费时间", index = 5)
@DateTimeFormat(value = "yyyy年MM月dd日HH时mm分ss秒", use1904windowing = BooleanEnum.TRUE)
private LocalDateTime moneyDateTimeStr;
/** 排名占比(%) */
@ExcelProperty(value = "排名占比", index = 6)
@NumberFormat("#.##%")
private String rate;
}
测试文件图片
(3)扩展:自定义导入解析监听器
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.example.demo.dto.DemoDto;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
@Slf4j
@Data
public class DemoListener implements ReadListener<DemoDto> {
public DemoListener() {
}
// // 业务板块,用户保存数据到数据库
//private BaseContractMaterialService baseContractMaterialService;
//public DemoListener(BaseContractMaterialService baseContractMaterialService) {
// this.baseContractMaterialService = baseContractMaterialService;
//}
/**
* 每隔100条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收
*/
private static final int BATCH_COUNT = 100;
/**
* 缓存的数据
*/
private List<DemoDto> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
@Override
public void invoke(DemoDto demoDto, AnalysisContext analysisContext) {
log.info("解析到一条数据:{}", JSONUtil.toJsonStr(demoDto));
cachedDataList.add(demoDto);
// 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
if (cachedDataList.size() >= BATCH_COUNT) {
this.saveData();
// 存储完成清理 list
cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
}
//log.info("解析数据完成");
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
// 这里也要保存数据,确保最后遗留的数据也存储到数据库
this.saveData();
log.info("所有数据解析完成!");
}
/**
* 加上存储数据库
*/
private void saveData() {
log.info("解析到【{}】条数据,开始存储数据库!", cachedDataList.size());
System.out.println("解析后的所有数据,如下所示:\n" + JSONUtil.toJsonStr(cachedDataList));
log.info("存储数据库成功!");
}
}
(4)测试案例
【1】 案例1:不使用监听器
/**
* 最简单的读
* <pre>
* 1. 创建excel对应的实体对象 参照{@link DemoDto}
* 2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoListener}
* 3. 直接读即可
* </pre>
*/
@Test
public void simpleRead() {
log.info("==========================写法1 不需要创建监听器===========================");
// 写法1:JDK8+ ,不用额外写一个DemoDataListener
// since: 3.0.0-beta1
//3.0.0版本之后,使用这种方法不需要创建监听器
String fileName = "D:\\testDemoExcel.xlsx";
List<DemoDto> dataItemList = new ArrayList<>();
// 这里默认每次会读取100条数据 然后返回过来 直接调用使用数据就行
// 具体需要返回多少行可以在`PageReadListener`的构造函数设置
EasyExcel.read(fileName, DemoDto.class, new PageReadListener<DemoDto>(dataList -> {
for (DemoDto demoData : dataList) {
dataItemList.add(demoData);
log.info("读取到一条数据{}", JSONUtil.toJsonStr(demoData));
}
})).sheet().doRead();
System.out.println("解析后的所有数据,如下所示:\n" + JSONUtil.toJsonStr(dataItemList));
}
亲自测试结果:
【2】案例2:匿名内部类
@Test
public void simpleRead2() {
log.info("==========================写法2 匿名内部类===========================");
// 写法2:
// 匿名内部类(创建一个监听器对象) 不用额外写一个DemoDataListener
String fileName = "D:\\testDemoExcel.xlsx";
// 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
EasyExcel.read(fileName, DemoDto.class, new ReadListener<DemoDto>() {
/**
* 单次缓存的数据量
*/
public static final int BATCH_COUNT = 100;
/**
*临时存储
*/
private List<DemoDto> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
@Override
public void invoke(DemoDto data, AnalysisContext context) {
cachedDataList.add(data);
if (cachedDataList.size() >= BATCH_COUNT) {
saveData();
// 存储完成清理 list
cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
saveData();
}
/**
* TODO 加上存储数据库
*/
private void saveData() {
log.info("解析到【{}】条数据,开始存储数据库!", cachedDataList.size());
System.out.println("解析后的所有数据,如下所示:\n" + JSONUtil.toJsonStr(cachedDataList));
log.info("存储数据库成功!");
}
}).sheet().doRead();
}
测试结果:
【3】案例3:需要创建监听器
@Test
public void simpleRead3() {
log.info("==========================写法3 需创建监听器===========================");
// 有个很重要的点 ContractMaterialDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
// 写法3:
//这种方法需要写一个监听器
String fileName = "D:\\testDemoExcel.xlsx";
// 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
EasyExcel.read(fileName, DemoDto.class, new DemoListener()).sheet().doRead();
}
亲自测试结果:
【4】案例4:读取单个文件多个 sheet
@Test
public void simpleRead4() {
log.info("==========================写法4 读单文件多个sheet===========================");
// 写法4
//这种方法可以读一个文件里的多个sheet
String fileName = "D:\\testDemoExcel.xlsx";
// 一个文件一个reader
try (ExcelReader excelReader = EasyExcel.read(fileName, DemoDto.class, new DemoListener()).build()) {
// 构建一个sheet 这里可以指定名字或者no
ReadSheet readSheet = EasyExcel.readSheet(0).build();
// 读取一个sheet
excelReader.read(readSheet);
}
}
亲自测试结果:
猜你喜欢
- 2024-09-09 jww基于springboot+dubbo分布式架构
- 2024-09-09 超实用的第三方开发工具库及开源项目
- 2024-09-09 基于springboot+dubbo分布式架构(spring boot+dubbo)
- 2024-09-09 软开企服开源的JVS开发套件(V2.1.3)产品说明书
- 2024-09-09 高效编程Hutool工具分析:Hutool设计方案与使用案例(第二部分)
- 2024-09-09 国内最火的几款Java开源项目(java最流行的开源软件)
- 2024-09-09 基于springboot+dubbo分布式架构jww
- 2024-09-09 只改了五行代码接口吞吐量提升了10多倍
- 2024-09-09 SpringBoot+Dubbo+Zookeeper+Redis+MQ分布式快速开发平台源码
- 2024-09-09 半个月收获接近 1k 的点赞!你需要的开源项目都在这里
你 发表评论:
欢迎- 07-08Google Cloud Platform 加入支持 Docker 的容器引擎
- 07-08日本KDDI与Google Cloud 签署合作备忘录,共探AI未来
- 07-08美国Infoblox与Google Cloud合作推出云原生网络和安全解决方案
- 07-08GoogleCloud为Spanner数据库引入HDD层,将冷存储成本降低80%
- 07-08谷歌推出Cloud Dataproc,缩短集群启动时间
- 07-08Infovista与Google Cloud携手推进射频网络规划革新
- 07-08比利时Odoo与Google Cloud建立增强合作,扩大全球影响力
- 07-08BT 和 Google Cloud 通过 Global Fabric 加速 AI 网络
- 最近发表
-
- Google Cloud Platform 加入支持 Docker 的容器引擎
- 日本KDDI与Google Cloud 签署合作备忘录,共探AI未来
- 美国Infoblox与Google Cloud合作推出云原生网络和安全解决方案
- GoogleCloud为Spanner数据库引入HDD层,将冷存储成本降低80%
- 谷歌推出Cloud Dataproc,缩短集群启动时间
- Infovista与Google Cloud携手推进射频网络规划革新
- 比利时Odoo与Google Cloud建立增强合作,扩大全球影响力
- BT 和 Google Cloud 通过 Global Fabric 加速 AI 网络
- NCSA和Google Cloud合作开发AI驱动的网络防御系统,加强泰国网络空间的安全性
- SAP将在沙特阿拉伯 Google Cloud 上推出BTP服务
- 标签列表
-
- ifneq (61)
- 字符串长度在线 (61)
- googlecloud (64)
- messagesource (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)