EasyExcel的简单使用

本文涉及的产品
可视分析地图(DataV-Atlas),3 个项目,100M 存储空间
简介: 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

相关实践学习
DataV Board用户界面概览
本实验带领用户熟悉DataV Board这款可视化产品的用户界面
阿里云实时数仓实战 - 项目介绍及架构设计
课程简介 1)学习搭建一个数据仓库的过程,理解数据在整个数仓架构的从采集、存储、计算、输出、展示的整个业务流程。 2)整个数仓体系完全搭建在阿里云架构上,理解并学会运用各个服务组件,了解各个组件之间如何配合联动。 3&nbsp;)前置知识要求 &nbsp; 课程大纲 第一章&nbsp;了解数据仓库概念 初步了解数据仓库是干什么的 第二章&nbsp;按照企业开发的标准去搭建一个数据仓库 数据仓库的需求是什么 架构 怎么选型怎么购买服务器 第三章&nbsp;数据生成模块 用户形成数据的一个准备 按照企业的标准,准备了十一张用户行为表 方便使用 第四章&nbsp;采集模块的搭建 购买阿里云服务器 安装 JDK 安装 Flume 第五章&nbsp;用户行为数据仓库 严格按照企业的标准开发 第六章&nbsp;搭建业务数仓理论基础和对表的分类同步 第七章&nbsp;业务数仓的搭建&nbsp; 业务行为数仓效果图&nbsp;&nbsp;
相关文章
|
7月前
|
Ubuntu Java Linux
在Spring Boot中使用iTextPDF创建动态PDF文档
iTextPDF 是一个用于创建和操作 PDF(Portable Document Format)文档的流行的 Java 库。它提供了一套全面的功能,用于处理 PDF 文件,包括创建新文档、修改现有文档以及提取信息。
424 1
|
1月前
|
存储 easyexcel Java
SpringBoot+EasyExcel轻松实现300万数据快速导出!
本文介绍了在项目开发中使用Apache POI进行数据导入导出的常见问题及解决方案。首先比较了HSSFWorkbook、XSSFWorkbook和SXSSFWorkbook三种传统POI版本的优缺点,然后根据数据量大小推荐了合适的使用场景。接着重点介绍了如何使用EasyExcel处理超百万数据的导入导出,包括分批查询、分批写入Excel、分批插入数据库等技术细节。通过测试,300万数据的导出用时约2分15秒,导入用时约91秒,展示了高效的数据处理能力。最后总结了公司现有做法的不足,并提出了改进方向。
|
2月前
|
JSON 算法 Java
hutool工具的简单使用
这篇文章介绍了Hutool工具库的基本使用,通过代码示例展示了如何利用Hutool进行字符串处理、文件操作、集合操作、加密解密、日期时间处理、网络请求和读取资源文件等常见任务。
50 0
hutool工具的简单使用
|
7月前
|
Java easyexcel 应用服务中间件
【二十五】springboot使用EasyExcel和线程池实现多线程导入Excel数据
【二十五】springboot使用EasyExcel和线程池实现多线程导入Excel数据
918 0
|
7月前
|
安全 Java Maven
【JavaEE进阶】 SpringBoot的创建与简单使用
【JavaEE进阶】 SpringBoot的创建与简单使用
|
7月前
|
存储 easyexcel Java
SpringBoot整合Easyexcel操作Excel,闲暇之余,让我们学习更多
SpringBoot整合Easyexcel操作Excel,闲暇之余,让我们学习更多
362 0
|
easyexcel API 数据安全/隐私保护
EasyExcel使用与详细说明,EasyExcel工具类(三)
EasyExcel使用与详细说明,EasyExcel工具类
9536 1
|
存储 JavaScript easyexcel
EasyExcel使用与详细说明,EasyExcel工具类(一)
EasyExcel使用与详细说明,EasyExcel工具类
1307 0
|
easyexcel
EasyExcel使用与详细说明,EasyExcel工具类(二)
EasyExcel使用与详细说明,EasyExcel工具类
986 0