文章标题
一: 使用场景
二: 技术选型
三: 常用API介绍
四: 测试
五: 总结
温馨提示: 本文总共6334字,阅读完大概需要6-8分钟,希望您能耐心看完,倘若你对该知识点已经比较熟悉,你可以直接通过目录跳转到你感兴趣的地方,希望阅读本文能够对您有所帮助,如果阅读过程中有什么好的建议、看法,欢迎在文章下方留言或者私信我,您的意见对我非常宝贵,再次感谢你阅读本文。
一: 使用场景
二: 技术选型
三: 常用API介绍
四: 测试
(一):添加依赖
// easyExcel坐标 <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>2.1.7</version> </dependency>
(二): JAVA映射实体
package com.elvis.easyexcel.model; import com.alibaba.excel.annotation.ExcelIgnore; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.format.DateTimeFormat; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; import java.util.Date; @Data @Builder @NoArgsConstructor @AllArgsConstructor public class Demo implements Serializable { private static final long serialVersionUID = -920481620956257604L; @ExcelIgnore @ExcelProperty(value = "姓名", index = 0) private String stringType; @ExcelProperty(value = "姓名2", index = 1) private Integer integerType; // 这里使用String类型接收才能格式化,如果使用Date类型则无法格式化 @ExcelProperty(value = "姓名3", index = 2) @DateTimeFormat("yyyy-MM-dd HH:mm:ss") private String dateType; @ExcelProperty(value = "姓名4", index = 3) private Double doubleType; @ExcelProperty(value = "姓名5", index = 4) private Long longType; @ExcelProperty(value = "姓名6", index = 5) private Float floatType; @ExcelProperty(value = "姓名7", index = 6) private Boolean booleanType; @ExcelProperty(value = "姓名8", index = 7) private Short shortType; }
(三): 添加监听器
package com.elvis.easyexcel.listener; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.exception.ExcelDataConvertException; import lombok.extern.slf4j.Slf4j; import org.json.JSONObject; import java.util.ArrayList; import java.util.List; import java.util.Objects; @Slf4j public class ObjectListener extends AnalysisEventListener<Object> { // 读取到的数据 private List<Object> readData = new ArrayList<>(); /** * 解析数据进入的方法 * @param o 本次读到的数据 * @param analysisContext */ @Override public void invoke(Object o, AnalysisContext analysisContext) { JSONObject jsonObject = new JSONObject(o); log.info("读取到的数据:{}", jsonObject.toString()); if(Objects.nonNull(o)){ readData.add(o); } } /** * 所有数据解析完成了 都会来调用 * @param analysisContext */ @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { log.info("所有数据解析完成了 都会来调用"); } /** * 在转换异常 获取其他异常下会调用本接口。抛出异常则停止读取。如果这里不抛出异常则 继续读取下一行。 * 如果你的程序在读取解析时即使有异常也不想后面的解析失败的,在此处打出解析错误日志即可 * 如果你的程序只有解析过程出错就解析解析的话,这在此处手动抛出异常即可 * @param exception * @param context * @throws Exception */ @Override public void onException(Exception exception, AnalysisContext context) { log.error("解析失败,但是继续解析下一行:{}", exception.getMessage()); // 如果是某一个单元格的转换异常 能获取到具体行号 // 如果要获取头的信息 配合invokeHeadMap使用 if (exception instanceof ExcelDataConvertException) { ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException)exception; log.error("第{}行,第{}列解析异常", excelDataConvertException.getRowIndex(), excelDataConvertException.getColumnIndex()); } } // 反馈解析完成的数据 public List<Object> getReadData(){ return readData; } }
(四): 书写工具类(这个工具类可以直接使用,如果有需要的,直接复制就可以)
package com.elvis.easyexcel.utils; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelReader; import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.write.builder.ExcelWriterBuilder; import com.alibaba.excel.write.metadata.WriteSheet; import com.elvis.easyexcel.listener.ObjectListener; import com.elvis.easyexcel.model.Demo; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.util.Collections; import java.util.List; @Slf4j public class EasyExcelUtils { /** * @param in 读取的文件流 * @param model 与excel文件数据对应的实体 * @param type 通用的数据读取解析监听器 * @return */ public static List<Object> readExcelFile(InputStream in, Object model, ObjectListener type) { ExcelReader reader = null; try { reader = EasyExcel.read(in, model.getClass(), type).build(); reader.readAll(); } catch (Exception e) { log.error("读取excel文件错误:" + e.getMessage()); return null; } finally { // 关闭流,读的时候会创建临时文件,不关闭到时磁盘会崩的 if (reader != null) { reader.finish(); } } return type.getReadData(); } /** * 保存数据到excel文件 * * @param data 数据(支持多个sheet写入,根据数据的个数写入对应个sheet,默认多个sheet写入的数据是同一个实体的) * @param savePath 保存的路径 * @return 是否保存成功 */ public static Boolean writeExcelFileWithCommonEntity(List<List<Object>> data, String savePath) { if (CollectionUtils.isNotEmpty(data)) { ExcelWriter excelWriter = null; // 输出流放到try的小括号中,方法结束时会自动关闭流,这个是jdk1.8的新特性,对于经常忘记关流的小伙伴很友好哦 try { // 获取到操作写入excel的操作对象,第二个参数是导出的excel文件的标题名对应的实体 // 获取写入数据中的第一个元素的类类型 excelWriter = EasyExcel.write(savePath).build(); // 设置每个sheet的名称 for (List<Object> objectList : data) { Object item = objectList.get(0); WriteSheet writeSheet = EasyExcel.writerSheet(1, "模板").head(item.getClass()).build(); excelWriter.write(objectList, writeSheet); } } catch (Exception e) { log.error("保存数据到excel错误:{}", e.getMessage()); return false; } finally { if (excelWriter != null) { excelWriter.finish(); } } } else { return false; } return true; } }
(五): 测试demo
package com.elvis; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.read.builder.ExcelReaderBuilder; import com.alibaba.excel.read.listener.ReadListener; import com.alibaba.excel.write.builder.ExcelWriterBuilder; import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder; import com.elvis.easyexcel.listener.ObjectListener; import com.elvis.easyexcel.model.Demo; import com.elvis.easyexcel.utils.EasyExcelUtils; import org.json.JSONArray; import org.junit.Test; import javax.jws.Oneway; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; public class demo { @Test public void demo1() throws Exception{ // 读取文件 System.out.println("开始读取文件------------------------------------"); String fileName = "E:\\newpath\\excelutils\\build\\classes\\小明.xlsx"; InputStream in = new FileInputStream(new File(fileName)); List<Object> objects = EasyExcelUtils.readExcelFile(in, new Demo(), new ObjectListener()); JSONArray array = new JSONArray(objects); System.out.println(array); System.out.println("--------------------------------------------------------------"); System.out.println("开始保存文件------------------------------------"); String savePath = "E:\\newpath\\excelutils\\build\\classes\\保存文件测试.xlsx"; List<List<Object>> data = new ArrayList<>(); List<Object> item = new ArrayList<>(); Demo abc = new Demo("abc",12,"2020-12-12 19:10:10",12.2,12l,12f,false,Short.parseShort("12")); item.add(abc); data.add(item); EasyExcelUtils.writeExcelFileWithCommonEntity(data,savePath); } }
(六): 效果展示
五: 总结