diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoCompatibleHeaderData.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoCompatibleHeaderData.java new file mode 100644 index 00000000..944a781d --- /dev/null +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoCompatibleHeaderData.java @@ -0,0 +1,23 @@ +package com.alibaba.easyexcel.test.demo.read; + +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; + +import java.util.Date; + +/** + * 多种表头上传支持的测试实体类 + * @author hccake + */ +@Data +public class DemoCompatibleHeaderData { + + @ExcelProperty("String") + private String string; + + @ExcelProperty("Date") + private Date date; + + @ExcelProperty("DoubleData") + private Double doubleData; +} diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoCompatibleHeaderDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoCompatibleHeaderDataListener.java new file mode 100644 index 00000000..2525854c --- /dev/null +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoCompatibleHeaderDataListener.java @@ -0,0 +1,97 @@ +package com.alibaba.easyexcel.test.demo.read; + +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; +import com.alibaba.excel.metadata.data.ReadCellData; +import com.alibaba.excel.util.ListUtils; +import com.alibaba.fastjson.JSON; +import lombok.extern.slf4j.Slf4j; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 读取头,兼容中英文传入 + * + * @author hccake + */ +@Slf4j +public class DemoCompatibleHeaderDataListener extends AnalysisEventListener { + + /** + * 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收 + */ + private static final int BATCH_COUNT = 100; + /** + * 缓存的数据 + */ + private List cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); + + /** + * 这里添加,各种表头到注解表头信息的映射 + */ + private Map headerMapping = new HashMap<>(8); + { + headerMapping.put("字符串标题", "String"); + headerMapping.put("日期标题", "Date"); + headerMapping.put("数字标题", "DoubleData"); + } + + + /** + * 这里会一行行的返回头 + * + * @param headMap + * @param context + */ + @Override + public void invokeHead(Map> headMap, AnalysisContext context) { + log.info("解析到一条头数据:{}", JSON.toJSONString(headMap)); + headMap.forEach((key, value) -> { + // 这里是根据 map 做的表头映射关系,实际可以根据自己的逻辑按需定制 + // 比如大小写转换,截取尾缀,删除空格,等等等等 + String stringValue = value.getStringValue(); + value.setStringValue(headerMapping.getOrDefault(stringValue, stringValue)); + }); + } + + + /** + * 这个每一条数据解析都会来调用 + * + * @param data one row value. Is is same as {@link AnalysisContext#readRowHolder()} + * @param context + */ + @Override + public void invoke(DemoCompatibleHeaderData data, AnalysisContext context) { + log.info("解析到一条数据:{}", JSON.toJSONString(data)); + cachedDataList.add(data); + // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM + if (cachedDataList.size() >= BATCH_COUNT) { + saveData(); + // 存储完成清理 list + cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); + } + } + + /** + * 所有数据解析完成了 都会来调用 + * + * @param context + */ + @Override + public void doAfterAllAnalysed(AnalysisContext context) { + // 这里也要保存数据,确保最后遗留的数据也存储到数据库 + saveData(); + log.info("所有数据解析完成!"); + } + + /** + * 加上存储数据库 + */ + private void saveData() { + log.info("{}条数据,开始存储数据库!", cachedDataList.size()); + log.info("存储数据库成功!"); + } +} diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java index 527ca6dc..ae10a631 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java @@ -200,6 +200,26 @@ public class ReadTest { .headRowNumber(1).doRead(); } + + /** + * 兼容性的表头上传,例如大小写同时支持,或者中英文同时支持 + * + *

+ * 1. 创建excel对应的实体对象 参照{@link DemoCompatibleHeaderData} + *

+ * 2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoCompatibleHeaderDataListener}, + * 且监听器种需要复写 invokeHead 方法,用来对上传的表头做转换 + *

+ * 3. 直接读即可 + */ + @Test + public void compatibleHeaderRead() { + String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx"; + // 这里 需要指定读用哪个class去读,然后读取第一个sheet + EasyExcel.read(fileName, DemoCompatibleHeaderData.class, new DemoCompatibleHeaderDataListener()).sheet().doRead(); + } + + /** * 读取表头数据 *