EasyExcel的简单使用

简介: EasyExcel的简单使用,以及如何通过postman进行导入导出功能的调试

1.基本介绍


EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。


依赖

<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.3</version></dependency>


2.简单的导出一个excel


对象

importcom.alibaba.excel.annotation.ExcelProperty;
importcom.alibaba.excel.annotation.format.DateTimeFormat;
importcom.alibaba.excel.annotation.write.style.ColumnWidth;
@DatapublicclassDemoExcel {
@ExcelProperty(value= {"数字"}, index=0)
@ColumnWidth(20)
privateDoubledoubleData;
@ExcelProperty(value= {"字符"}, index=1)
@ColumnWidth(20)
privateStringstring;
/*** 自定义的时间格式*/@DateTimeFormat("yyyy年MM月dd日 HH:mm:ss")
@ExcelProperty(value= {"时间"}, index=2)
@ColumnWidth(30)
privateDatedate;
}


Controller

importcom.alibaba.excel.EasyExcel;
@GetMapping("/download")
publicvoiddownload(HttpServletResponseresponse) {
// 模拟从数据库查询数据,不一定要转成demoExcel对象,只要字段能对应上就行List<DemoExcel>list=getList();
try {
// 导出数据response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
StringfileName=URLEncoder.encode(StringUtils.join(System.currentTimeMillis(), "_", "downloadExcel"), "UTF-8");
response.setHeader("Content-disposition", "attachment;filename="+fileName+".xlsx");
EasyExcel.write(response.getOutputStream(), DemoExcel.class).sheet("sheet1")
            .doWrite(list);
    } catch (Exceptione) {
log.debug("导出文件失败:{}", e.getMessage());
thrownewRuntimeException("导出文件失败");
    }
}


使用postman调试

点击send and download就能下载到excel

如果excel打不开,报错,多半是抛异常了,可以右键用记事本打开看到返回的json,也可以直接点一下send再调一次接口直接看到报错信息


3.简单的导入一个excel

对象

importcom.alibaba.excel.annotation.ExcelProperty;
importcom.alibaba.excel.annotation.format.DateTimeFormat;
importcom.alibaba.excel.annotation.write.style.ColumnWidth;
@DatapublicclassDemoExcel {
@ExcelProperty(value= {"数字"}, index=0)
@ColumnWidth(20)
privateDoubledoubleData;
@ExcelProperty(value= {"字符"}, index=1)
@ColumnWidth(20)
privateStringstring;
/*** 自定义的时间格式*/@DateTimeFormat("yyyy年MM月dd日 HH:mm:ss")
@ExcelProperty(value= {"时间"}, index=2)
@ColumnWidth(30)
privateDatedate;
}


监听

importcom.alibaba.excel.context.AnalysisContext;
importcom.alibaba.excel.event.AnalysisEventListener;
@Data@Slf4jpublicclassDemoDataListenerextendsAnalysisEventListener<DemoExcel> {
privateList<DemoExcel>list=newArrayList();
@Overridepublicvoidinvoke(DemoExceldata, AnalysisContextcontext) {
// 这里取到的data就是单独的一行数据,也可以在这个方法里对数据进行一些简单的处理list.add(data);
 }
@OverridepublicvoiddoAfterAllAnalysed(AnalysisContextcontext) {
// 这个方法是在excel解析完成后能对数据进行操作,也能在这里对数据进行各种处理log.info("获取数据量:"+list.size());
 }
}

Controller

importcom.alibaba.excel.EasyExcel;
@PostMapping("/upload")
publicvoidupload(@RequestParam("file") MultipartFilefile) throwsIOException {
DemoDataListenerlistener=newDemoDataListener();
//headRowNumber(1)从第二行读数据//sheet()默认读第一个sheet页,当然想读第二页就往里填个1EasyExcel.read(file.getInputStream(), DemoExcel.class, listener).sheet().headRowNumber(1).doRead();
List<DemoExcel>list=listener.getList();
// 我们取到了excel中的数据后就能用来进行想要的操作了list.forEach(s-> {
log.info("读取到数据------"+s);
    });
}



使用postman调试

我还是用刚才导出来的那个文件进行一次导入

postman向上面这样设置就能进行导入文件了

控制台的日志告诉我取到了这个数组


4.导出的excel要自带下拉框,以及多个sheet页的导出


Controller

importcom.alibaba.excel.EasyExcel;
importcom.alibaba.excel.ExcelWriter;
importcom.alibaba.excel.write.metadata.WriteSheet;
importcom.alibaba.excel.write.metadata.WriteTable;
@GetMapping("/download/default")
publicvoiddownloadDefault(HttpServletResponseresponse) {
try {
// 导出数据response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系StringfileName=URLEncoder.encode(StringUtils.join(System.currentTimeMillis(), "_", "downloadExcel"), "UTF-8");
response.setHeader("Content-disposition", "attachment;filename="+fileName+".xlsx");
ExcelWriterwriter=EasyExcel.write(response.getOutputStream()).build();
// 预设值List<DefaultData>defaultData=getDefault();
// 设置第1个sheet为我们的模版 同时设置一个下拉框// 把sheet设置为不需要头 不然会输出sheet的头 这样看起来第一个table 就有2个头了WriteSheetwriteSheet=EasyExcel.writerSheet(0,"模板").needHead(false)
            .registerWriteHandler(newCustomSheetWriteHandler(defaultData))
            .build();
// 填写表单的表头WriteTablewriteTable0=EasyExcel.writerTable(0).needHead(true).build();
writeTable0.setClazz(DemoExcel.class);
writer.write(Lists.newArrayList(), writeSheet, writeTable0);
// 根据预设值的pid整理一下List<DemoDefaultExcel>defaultExcelList=getFormDataList(defaultData);
// 设置第2个sheet为字段可选范围 ,把可以选择的范围列出来,没有也没事WriteSheetwriteDefaultDataSheet=EasyExcel.writerSheet(1,"字段选填范围")
            .head(DemoDefaultExcel.class).build();
writer.write(defaultExcelList, writeDefaultDataSheet);
writer.finish();
    } catch (Exceptione) {
log.debug("导出文件失败:{}", e.getMessage());
thrownewRuntimeException("导出文件失败");
    }
}


Handler

importcom.alibaba.excel.write.handler.SheetWriteHandler;
importcom.alibaba.excel.write.metadata.holder.WriteSheetHolder;
importcom.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
importorg.apache.poi.ss.usermodel.DataValidation;
importorg.apache.poi.ss.usermodel.DataValidationConstraint;
importorg.apache.poi.ss.usermodel.DataValidationHelper;
importorg.apache.poi.ss.util.CellRangeAddressList;
publicclassCustomSheetWriteHandlerimplementsSheetWriteHandler {
privateList<DefaultData>defaultDataList;
publicCustomSheetWriteHandler(List<DefaultData>defaultDataList){
this.defaultDataList=defaultDataList;
    }
@OverridepublicvoidbeforeSheetCreate(WriteWorkbookHolderwriteWorkbookHolder, WriteSheetHolderwriteSheetHolder) {
    }
@OverridepublicvoidafterSheetCreate(WriteWorkbookHolderwriteWorkbookHolder, WriteSheetHolderwriteSheetHolder) {
// 筛选出pid为1的值,添加到第2列的下拉框中writeSheetHolder.getSheet().addValidationData(getValidationDataByPid(1L, 1, writeSheetHolder));
writeSheetHolder.getSheet().addValidationData(getValidationDataByPid(2L, 2, writeSheetHolder));
    }
privateDataValidationgetValidationDataByPid(Longpid, intcol, WriteSheetHolderwriteSheetHolder){
List<String>dataValues=defaultDataList.stream().filter(item->null!=item.getPid() &&item.getPid().equals(pid))
                .map(DefaultData::getNodeName).collect(Collectors.toList());
returngetValidationDataBySelects(writeSheetHolder, col, dataValues.toArray(newString[dataValues.size()]));
    }
privateDataValidationgetValidationDataBySelects(WriteSheetHolderwriteSheetHolder, intcol, String[] valus){
// 这里4个参数代表从第二行到第65536行,从第几列到第几列。可以根据需求增加CellRangeAddressListcellRangeAddressList=newCellRangeAddressList(1, 65535, col, col);
DataValidationHelperhelper=writeSheetHolder.getSheet().getDataValidationHelper();
DataValidationConstraintconstraint=helper.createExplicitListConstraint(valus);
DataValidationdataValidation=helper.createValidation(constraint, cellRangeAddressList);
returndataValidation;
    }
}


DefaultData.java

@DatapublicclassDefaultData {
privateLongpid;
privateStringnodeName;
}



预设值的结构是这样的


导出的文件第一页,第二列和第三列有了下拉框选项


第二页有可选范围的示范


5.导出的excel要有示例

DemoExampleExcel.java

importcom.alibaba.excel.annotation.ExcelProperty;
importcom.alibaba.excel.annotation.format.DateTimeFormat;
importcom.alibaba.excel.annotation.write.style.ColumnWidth;
importcom.alibaba.excel.annotation.write.style.ContentStyle;
importcom.alibaba.excel.annotation.write.style.HeadStyle;
importorg.apache.poi.ss.usermodel.FillPatternType;
@Data// 以注解形式设置样式// 头背景设置成黄色 IndexedColors.YELLOW.getIndex()@HeadStyle(fillPatternType=FillPatternType.SOLID_FOREGROUND, fillForegroundColor=13)
// 内容的背景设置成黄色 IndexedColors.YELLOW.getIndex()@ContentStyle(fillPatternType=FillPatternType.SOLID_FOREGROUND, fillForegroundColor=13)
publicclassDemoExampleExcel {
// 相同的表头会自动合并@ExcelProperty(value= {"示例", "示例", "数字"}, index=0)
@ColumnWidth(20)
privateDoubledoubleData;
@ExcelProperty(value= {"示例", "示例", "字符"}, index=1)
@ColumnWidth(20)
privateStringstring;
@ExcelProperty(value= {"示例", "示例", "字符2"}, index=2)
@ColumnWidth(20)
privateStringstring2;
@DateTimeFormat("yyyy年MM月dd日 HH:mm:ss")
@ExcelProperty(value= {"示例", "示例", "时间"}, index=3)
@ColumnWidth(30)
privateDatedate;
}


Controller

importcom.alibaba.excel.EasyExcel;
importcom.alibaba.excel.ExcelWriter;
importcom.alibaba.excel.write.metadata.WriteSheet;
importcom.alibaba.excel.write.metadata.WriteTable;
@GetMapping("/download/example")
publicvoiddownloadExample(HttpServletResponseresponse) {
try {
// 导出数据response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系StringfileName=URLEncoder.encode(StringUtils.join(System.currentTimeMillis(), "_", "downloadExcel"), "UTF-8");
response.setHeader("Content-disposition", "attachment;filename="+fileName+".xlsx");
ExcelWriterwriter=EasyExcel.write(response.getOutputStream()).build();
// 把sheet设置为不需要头 不然会输出sheet的头 这样看起来第一个table 就有2个头了WriteSheetwriteSheet=EasyExcel.writerSheet(0,"模板").needHead(false).build();
// 获取示例list 填写示例List<DemoExampleExcel>exampleExcels=getExampleList();
WriteTablewriteTable0=EasyExcel.writerTable(0).needHead(true).build();
writeTable0.setClazz(DemoExampleExcel.class);
writer.write(exampleExcels, writeSheet, writeTable0);
// 示例和表头间增加一栏空行writer.write(Lists.newArrayList(""), writeSheet);
// 填写表单的表头WriteTablewriteTable1=EasyExcel.writerTable(1).needHead(true).build();
writeTable1.setClazz(DemoExcel.class);
writer.write(Lists.newArrayList(), writeSheet, writeTable1);
writer.finish();
    } catch (Exceptione) {
log.debug("导出文件失败:{}", e.getMessage());
thrownewRuntimeException("导出文件失败");
    }
}


这里只列举了几种实用并且可能用的上的小功能。

更多的进阶技巧可以查看官方语雀。也欢迎大家继续补充这篇文章。

6.参考资料


github地址:https://github.com/alibaba/easyexcel

官方语雀:https://www.yuque.com/easyexcel/doc/easyexcel

相关实践学习
基于Hologres轻量实时的高性能OLAP分析
本教程基于GitHub Archive公开数据集,通过DataWorks将GitHub中的项⽬、行为等20多种事件类型数据实时采集至Hologres进行分析,同时使用DataV内置模板,快速搭建实时可视化数据大屏,从开发者、项⽬、编程语⾔等多个维度了解GitHub实时数据变化情况。
阿里云实时数仓实战 - 用户行为数仓搭建
课程简介 1)学习搭建一个数据仓库的过程,理解数据在整个数仓架构的从采集、存储、计算、输出、展示的整个业务流程。 2)整个数仓体系完全搭建在阿里云架构上,理解并学会运用各个服务组件,了解各个组件之间如何配合联动。 3&nbsp;)前置知识要求:熟练掌握 SQL 语法熟悉 Linux 命令,对 Hadoop 大数据体系有一定的了解 &nbsp; 课程大纲 第一章&nbsp;了解数据仓库概念 初步了解数据仓库是干什么的 第二章&nbsp;按照企业开发的标准去搭建一个数据仓库 数据仓库的需求是什么 架构 怎么选型怎么购买服务器 第三章&nbsp;数据生成模块 用户形成数据的一个准备 按照企业的标准,准备了十一张用户行为表 方便使用 第四章&nbsp;采集模块的搭建 购买阿里云服务器 安装 JDK 安装 Flume 第五章&nbsp;用户行为数据仓库 严格按照企业的标准开发 第六章&nbsp;搭建业务数仓理论基础和对表的分类同步 第七章&nbsp;业务数仓的搭建&nbsp; 业务行为数仓效果图&nbsp;&nbsp;
相关文章
|
存储 easyexcel Java
EasyExcel教程
EasyExcel教程
16676 0
|
前端开发 easyexcel Java
Java+EasyExcel实现文件导入导出,导入导出如此简单
项目中需要Excel文件的导入与导出Excel并下载,例如,导入员工信息,导出员工信息,手动输入比较繁琐,所以本篇博文教大家如何在Java中导入Excel文件与导出Excel文件
15578 3
Java+EasyExcel实现文件导入导出,导入导出如此简单
|
easyexcel Java
EasyExcel的使用
EasyExcel的使用
419 0
|
前端开发 Java 数据库
Java系列之 Long类型返回前端精度丢失
这篇文章讨论了Java后端实体类中Long类型数据在传递给前端时出现的精度丢失问题,并提供了通过在实体类字段上添加`@JsonSerialize(using = ToStringSerializer.class)`注解来确保精度的解决方法。
|
easyexcel Java 关系型数据库
阿里巴巴-EasyExcel 基于Java的简单、省内存的读写Excel
该文章主要介绍了在Java应用中如何使用EasyExcel技术完成对Excel文件的导入和导出操作,包括环境搭建、基本概念、快速入门、进阶操作和综合应用等内容,并提供了相关代码示例和注意事项。
 阿里巴巴-EasyExcel 基于Java的简单、省内存的读写Excel
|
存储 数据采集 数据挖掘
“湖仓一体架构及其应用”写作框架,系统架构设计师
随着5G、大数据、人工智能、物联网等技术的不断成熟,各行各业的业务场景日益复杂,企业数据呈现出大规模、多样性的特点,特别是非结构化数据呈现出爆发式增长趋势。在这一背景下,企业数据管理不再局限于传统的结构化OLTP(On-Line Transaction Processing)数据交易过程,而是提出了多样化、异质性数据的实时处理要求。传统的数据湖(Data Lake)在事务一致性及实时处理方面有所欠缺,而数据仓库(Data Warehouse)也无法应对高并发、多数据类型的处理。因此,支持事务一致性、提供高并发实时处理及分析能力的湖仓一体(Lake House)架构应运而生。湖仓一体架构在成本、
455 2
|
easyexcel Java API
Apache POI、EasyPoi、EasyExcel 三种区别,如何选择
Apache POI、EasyPoi、EasyExcel 三种区别,如何选择
2128 0
|
SQL 存储 测试技术
SQL Server 查询超时问题排查
【8月更文挑战第14天】遇到SQL Server查询超时,先检查查询复杂度与索引使用;审视服务器CPU、内存及磁盘I/O负载;审查SQL Server配置与超时设置;检测锁和阻塞状况;最后审查应用代码与网络环境。每步定位问题根源,针对性优化以提升查询效率。务必先行备份并在测试环境验证改动。
1017 0
|
编解码 人工智能
PixArt-Σ:华为最新文生图模型,支持4K高清图像生成
【5月更文挑战第18天】华为发布PixArt-Σ模型,一款基于DiT架构的4K图像生成器,提升图像质量和文本对齐度。模型采用“弱到强训练”,以少量参数生成优质图像。引入高质量数据和高效标记压缩方法,实现超高分辨率图像生成。实验显示,PixArt-Σ在遵循复杂文本提示和图像质量上表现优异,与顶尖T2I模型相当。然而,计算资源需求大及处理复杂场景能力有限仍是待解问题。[链接](https://arxiv.org/pdf/2403.04692.pdf)
412 1
|
监控 Dubbo Java
超详细的Sentinel入门
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
超详细的Sentinel入门