From 0b4e334044d0d2f9bb14e5988c0243f00d7b3023 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Fri, 13 May 2022 15:37:57 +0800 Subject: [PATCH 01/68] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F=E7=9A=84=E6=83=85=E5=86=B5=E4=B8=8B=E4=B8=8D?= =?UTF-8?q?=E4=BC=9A=E7=A9=BA=E6=8C=87=E9=92=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../read/metadata/holder/xlsx/XlsxReadWorkbookHolder.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/xlsx/XlsxReadWorkbookHolder.java b/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/xlsx/XlsxReadWorkbookHolder.java index 4e70aa0e..c5d78e0f 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/xlsx/XlsxReadWorkbookHolder.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/xlsx/XlsxReadWorkbookHolder.java @@ -65,6 +65,9 @@ public class XlsxReadWorkbookHolder extends ReadWorkbookHolder { return null; } XSSFCellStyle xssfCellStyle = stylesTable.getStyleAt(dateFormatIndexInteger); + if (xssfCellStyle == null) { + return null; + } dataFormatData.setIndex(xssfCellStyle.getDataFormat()); dataFormatData.setFormat(BuiltinFormats.getBuiltinFormat(dataFormatData.getIndex(), xssfCellStyle.getDataFormatString(), globalConfiguration().getLocale())); From 77225bcea39b3ec4365d007b0a51a5cd041e8d11 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Thu, 19 May 2022 21:10:13 +0800 Subject: [PATCH 02/68] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=96=87=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/alibaba/easyexcel/test/demo/read/ReadTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 d621c300..87d4481f 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 @@ -47,7 +47,7 @@ public class ReadTest { // since: 3.0.0-beta1 String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx"; // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭 - // 这里每次会读取3000条数据 然后返回过来 直接调用使用数据就行 + // 这里每次会读取100条数据 然后返回过来 直接调用使用数据就行 EasyExcel.read(fileName, DemoData.class, new PageReadListener(dataList -> { for (DemoData demoData : dataList) { log.info("读取到一条数据{}", JSON.toJSONString(demoData)); From de9a63d6dfb9ecd1e2787f5452433c021bbf20b6 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Tue, 31 May 2022 16:01:46 +0800 Subject: [PATCH 03/68] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8eafb40f..101e4634 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,8 @@ EasyExcel [QQ1群(已满): 662022184](https://jq.qq.com/?_wv=1027&k=1T21jJxh) [QQ2群(已满): 1097936804](https://jq.qq.com/?_wv=1027&k=j5zEy6Xl) [QQ3群(已满): 453928496](https://qm.qq.com/cgi-bin/qm/qr?k=e2ULsA5A0GldhV2CXJ8sIbAyu9I6qqs7&jump_from=webapi) -[QQ4群: 496594404](https://qm.qq.com/cgi-bin/qm/qr?k=e_aVG1Q7gi0PJUBkbrUGAgbeO3kUEInK&jump_from=webapi) +[QQ4群(已满): 496594404](https://qm.qq.com/cgi-bin/qm/qr?k=e_aVG1Q7gi0PJUBkbrUGAgbeO3kUEInK&jump_from=webapi) +[QQ5群: 203228638](https://jq.qq.com/?_wv=1027&k=m9kqpoV6) [钉钉1群(已满): 21960511](https://qr.dingtalk.com/action/joingroup?code=v1,k1,cchz6k12ci9B08NNqhNRFGXocNVHrZtW0kaOtTKg/Rk=&_dt_no_comment=1&origin=11) [钉钉2群(已满): 32796397](https://qr.dingtalk.com/action/joingroup?code=v1,k1,jyU9GtEuNU5S0QTyklqYcYJ8qDZtUuTPMM7uPZTS8Hs=&_dt_no_comment=1&origin=11) [钉钉3群(已满): 33797247](https://qr.dingtalk.com/action/joingroup?code=v1,k1,3UGlEScTGQaHpW2cIRo+gkxJ9EVZ5fz26M6nW3uFP30=&_dt_no_comment=1&origin=11) From 0e546c3956605ef67b7d2ad68f8815fe00cad5df Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 1 Jun 2022 17:26:15 +0800 Subject: [PATCH 04/68] =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=A4=9A=E4=BD=99?= =?UTF-8?q?=E6=A1=88=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../easyexcel/test/demo/fill/FillTest.java | 129 +----------------- .../easyexcel/test/demo/read/ReadTest.java | 40 +----- .../easyexcel/test/demo/write/WriteTest.java | 107 +-------------- 3 files changed, 12 insertions(+), 264 deletions(-) diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/fill/FillTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/fill/FillTest.java index 0c71753e..618a030f 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/fill/FillTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/fill/FillTest.java @@ -83,28 +83,13 @@ public class FillTest { return data(); }); - // 方案3.1 分多次 填充 会使用文件缓存(省内存) 使用 try-with-resources @since 3.1.0 + // 方案3 分多次 填充 会使用文件缓存(省内存) fileName = TestFileUtil.getPath() + "listFill" + System.currentTimeMillis() + ".xlsx"; try (ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build()) { WriteSheet writeSheet = EasyExcel.writerSheet().build(); excelWriter.fill(data(), writeSheet); excelWriter.fill(data(), writeSheet); } - - // 方案3.2 分多次 填充 会使用文件缓存(省内存) 不使用 try-with-resources - fileName = TestFileUtil.getPath() + "listFill" + System.currentTimeMillis() + ".xlsx"; - ExcelWriter excelWriter = null; - try { - excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build(); - WriteSheet writeSheet = EasyExcel.writerSheet().build(); - excelWriter.fill(data(), writeSheet); - excelWriter.fill(data(), writeSheet); - } finally { - // 千万别忘记close 会帮忙关闭流 - if (excelWriter != null) { - excelWriter.close(); - } - } } /** @@ -120,7 +105,7 @@ public class FillTest { TestFileUtil.getPath() + "demo" + File.separator + "fill" + File.separator + "complex.xlsx"; String fileName = TestFileUtil.getPath() + "complexFill" + System.currentTimeMillis() + ".xlsx"; - // 方案1 : 使用 try-with-resources @since 3.1.0 + // 方案1 try (ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build()) { WriteSheet writeSheet = EasyExcel.writerSheet().build(); // 这里注意 入参用了forceNewRow 代表在写入list的时候不管list下面有没有空行 都会创建一行,然后下面的数据往后移动。默认 是false,会直接使用下一行,如果没有则创建。 @@ -135,29 +120,6 @@ public class FillTest { map.put("total", 1000); excelWriter.fill(map, writeSheet); } - - // 方案2 : 不使用 try-with-resources - ExcelWriter excelWriter = null; - try { - excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build(); - WriteSheet writeSheet = EasyExcel.writerSheet().build(); - // 这里注意 入参用了forceNewRow 代表在写入list的时候不管list下面有没有空行 都会创建一行,然后下面的数据往后移动。默认 是false,会直接使用下一行,如果没有则创建。 - // forceNewRow 如果设置了true,有个缺点 就是他会把所有的数据都放到内存了,所以慎用 - // 简单的说 如果你的模板有list,且list不是最后一行,下面还有数据需要填充 就必须设置 forceNewRow=true 但是这个就会把所有数据放到内存 会很耗内存 - // 如果数据量大 list不是最后一行 参照下一个 - FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build(); - excelWriter.fill(data(), fillConfig, writeSheet); - excelWriter.fill(data(), fillConfig, writeSheet); - Map map = MapUtils.newHashMap(); - map.put("date", "2019年10月9日13:28:28"); - map.put("total", 1000); - excelWriter.fill(map, writeSheet); - } finally { - // 千万别忘记close 会帮忙关闭流 - if (excelWriter != null) { - excelWriter.close(); - } - } } /** @@ -177,7 +139,7 @@ public class FillTest { String fileName = TestFileUtil.getPath() + "complexFillWithTable" + System.currentTimeMillis() + ".xlsx"; - // 方案1 : 使用 try-with-resources @since 3.1.0 + // 方案1 try (ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build()) { WriteSheet writeSheet = EasyExcel.writerSheet().build(); // 直接写入数据 @@ -204,42 +166,6 @@ public class FillTest { // 总体上写法比较复杂 但是也没有想到好的版本 异步的去写入excel 不支持行的删除和移动,也不支持备注这种的写入,所以也排除了可以 // 新建一个 然后一点点复制过来的方案,最后导致list需要新增行的时候,后面的列的数据没法后移,后续会继续想想解决方案 } - - // 方案2 : 不使用 try-with-resources - ExcelWriter excelWriter = null; - try { - excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build(); - WriteSheet writeSheet = EasyExcel.writerSheet().build(); - // 直接写入数据 - excelWriter.fill(data(), writeSheet); - excelWriter.fill(data(), writeSheet); - - // 写入list之前的数据 - Map map = new HashMap(); - map.put("date", "2019年10月9日13:28:28"); - excelWriter.fill(map, writeSheet); - - // list 后面还有个统计 想办法手动写入 - // 这里偷懒直接用list 也可以用对象 - List> totalListList = ListUtils.newArrayList(); - List totalList = ListUtils.newArrayList(); - totalListList.add(totalList); - totalList.add(null); - totalList.add(null); - totalList.add(null); - // 第四列 - totalList.add("统计:1000"); - // 这里是write 别和fill 搞错了 - excelWriter.write(totalListList, writeSheet); - - // 总体上写法比较复杂 但是也没有想到好的版本 异步的去写入excel 不支持行的删除和移动,也不支持备注这种的写入,所以也排除了可以 - // 新建一个 然后一点点复制过来的方案,最后导致list需要新增行的时候,后面的列的数据没法后移,后续会继续想想解决方案 - } finally { - // 千万别忘记close 会帮忙关闭流 - if (excelWriter != null) { - excelWriter.close(); - } - } } /** @@ -255,7 +181,7 @@ public class FillTest { TestFileUtil.getPath() + "demo" + File.separator + "fill" + File.separator + "horizontal.xlsx"; String fileName = TestFileUtil.getPath() + "horizontalFill" + System.currentTimeMillis() + ".xlsx"; - // 方案1 : 使用 try-with-resources @since 3.1.0 + // 方案1 try (ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build()) { WriteSheet writeSheet = EasyExcel.writerSheet().build(); FillConfig fillConfig = FillConfig.builder().direction(WriteDirectionEnum.HORIZONTAL).build(); @@ -266,25 +192,6 @@ public class FillTest { map.put("date", "2019年10月9日13:28:28"); excelWriter.fill(map, writeSheet); } - - // 方案2 : 不使用 try-with-resources - ExcelWriter excelWriter = null; - try { - excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build(); - WriteSheet writeSheet = EasyExcel.writerSheet().build(); - FillConfig fillConfig = FillConfig.builder().direction(WriteDirectionEnum.HORIZONTAL).build(); - excelWriter.fill(data(), fillConfig, writeSheet); - excelWriter.fill(data(), fillConfig, writeSheet); - - Map map = new HashMap(); - map.put("date", "2019年10月9日13:28:28"); - excelWriter.fill(map, writeSheet); - } finally { - // 千万别忘记close 会帮忙关闭流 - if (excelWriter != null) { - excelWriter.close(); - } - } } /** @@ -301,7 +208,7 @@ public class FillTest { String fileName = TestFileUtil.getPath() + "compositeFill" + System.currentTimeMillis() + ".xlsx"; - // 方案1 : 使用 try-with-resources @since 3.1.0 + // 方案1 try (ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build()) { WriteSheet writeSheet = EasyExcel.writerSheet().build(); FillConfig fillConfig = FillConfig.builder().direction(WriteDirectionEnum.HORIZONTAL).build(); @@ -319,32 +226,6 @@ public class FillTest { excelWriter.fill(map, writeSheet); } - - // 方案2 : 不使用 try-with-resources - ExcelWriter excelWriter = null; - try { - excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build(); - WriteSheet writeSheet = EasyExcel.writerSheet().build(); - FillConfig fillConfig = FillConfig.builder().direction(WriteDirectionEnum.HORIZONTAL).build(); - // 如果有多个list 模板上必须有{前缀.} 这里的前缀就是 data1,然后多个list必须用 FillWrapper包裹 - excelWriter.fill(new FillWrapper("data1", data()), fillConfig, writeSheet); - excelWriter.fill(new FillWrapper("data1", data()), fillConfig, writeSheet); - excelWriter.fill(new FillWrapper("data2", data()), writeSheet); - excelWriter.fill(new FillWrapper("data2", data()), writeSheet); - excelWriter.fill(new FillWrapper("data3", data()), writeSheet); - excelWriter.fill(new FillWrapper("data3", data()), writeSheet); - - Map map = new HashMap(); - //map.put("date", "2019年10月9日13:28:28"); - map.put("date", new Date()); - - excelWriter.fill(map, writeSheet); - } finally { - // 千万别忘记close 会帮忙关闭流 - if (excelWriter != null) { - excelWriter.close(); - } - } } private List data() { 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 87d4481f..527ca6dc 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 @@ -98,7 +98,7 @@ public class ReadTest { // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭 EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).sheet().doRead(); - // 写法4: 使用 try-with-resources @since 3.1.0 + // 写法4 fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx"; // 一个文件一个reader try (ExcelReader excelReader = EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).build()) { @@ -107,23 +107,6 @@ public class ReadTest { // 读取一个sheet excelReader.read(readSheet); } - - // 写法5: 不使用 try-with-resources - fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx"; - // 一个文件一个reader - ExcelReader excelReader = null; - try { - excelReader = EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).build(); - // 构建一个sheet 这里可以指定名字或者no - ReadSheet readSheet = EasyExcel.readSheet(0).build(); - // 读取一个sheet - excelReader.read(readSheet); - } finally { - if (excelReader != null) { - // 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的 - excelReader.close(); - } - } } /** @@ -162,7 +145,7 @@ public class ReadTest { // 读取部分sheet fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx"; - // 写法1: 使用 try-with-resources @since 3.1.0 + // 写法1 try (ExcelReader excelReader = EasyExcel.read(fileName).build()) { // 这里为了简单 所以注册了 同样的head 和Listener 自己使用功能必须不同的Listener ReadSheet readSheet1 = @@ -172,25 +155,6 @@ public class ReadTest { // 这里注意 一定要把sheet1 sheet2 一起传进去,不然有个问题就是03版的excel 会读取多次,浪费性能 excelReader.read(readSheet1, readSheet2); } - - // 写法2: 不使用 try-with-resources - ExcelReader excelReader = null; - try { - excelReader = EasyExcel.read(fileName).build(); - - // 这里为了简单 所以注册了 同样的head 和Listener 自己使用功能必须不同的Listener - ReadSheet readSheet1 = - EasyExcel.readSheet(0).head(DemoData.class).registerReadListener(new DemoDataListener()).build(); - ReadSheet readSheet2 = - EasyExcel.readSheet(1).head(DemoData.class).registerReadListener(new DemoDataListener()).build(); - // 这里注意 一定要把sheet1 sheet2 一起传进去,不然有个问题就是03版的excel 会读取多次,浪费性能 - excelReader.read(readSheet1, readSheet2); - } finally { - if (excelReader != null) { - // 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的 - excelReader.close(); - } - } } /** diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java index f7d015ca..607a91be 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java @@ -86,28 +86,13 @@ public class WriteTest { // 如果这里想使用03 则 传入excelType参数即可 EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(data()); - // 写法3:使用 try-with-resources @since 3.1.0 + // 写法3 fileName = TestFileUtil.getPath() + "simpleWrite" + System.currentTimeMillis() + ".xlsx"; // 这里 需要指定写用哪个class去写 try (ExcelWriter excelWriter = EasyExcel.write(fileName, DemoData.class).build()) { WriteSheet writeSheet = EasyExcel.writerSheet("模板").build(); excelWriter.write(data(), writeSheet); } - - // 写法4: 不使用 try-with-resources - fileName = TestFileUtil.getPath() + "simpleWrite" + System.currentTimeMillis() + ".xlsx"; - // 这里 需要指定写用哪个class去写 - ExcelWriter excelWriter = null; - try { - excelWriter = EasyExcel.write(fileName, DemoData.class).build(); - WriteSheet writeSheet = EasyExcel.writerSheet("模板").build(); - excelWriter.write(data(), writeSheet); - } finally { - // 千万别忘记close 会帮忙关闭流 - if (excelWriter != null) { - excelWriter.close(); - } - } } /** @@ -185,7 +170,7 @@ public class WriteTest { */ @Test public void repeatedWrite() { - // 方法1.1: 如果写到同一个sheet 使用 try-with-resources @since 3.1.0 + // 方法1: 如果写到同一个sheet String fileName = TestFileUtil.getPath() + "repeatedWrite" + System.currentTimeMillis() + ".xlsx"; // 这里 需要指定写用哪个class去写 try (ExcelWriter excelWriter = EasyExcel.write(fileName, DemoData.class).build()) { @@ -199,28 +184,7 @@ public class WriteTest { } } - // 方法1.2: 如果写到同一个sheet 不使用 try-with-resources - fileName = TestFileUtil.getPath() + "repeatedWrite" + System.currentTimeMillis() + ".xlsx"; - ExcelWriter writer = null; - try { - // 这里 需要指定写用哪个class去写 - writer = EasyExcel.write(fileName, DemoData.class).build(); - // 这里注意 如果同一个sheet只要创建一次 - WriteSheet writeSheet = EasyExcel.writerSheet("模板").build(); - // 去调用写入,这里我调用了五次,实际使用时根据数据库分页的总的页数来 - for (int i = 0; i < 5; i++) { - // 分页去数据库查询数据 这里可以去数据库查询每一页的数据 - List data = data(); - writer.write(data, writeSheet); - } - } finally { - // 千万别忘记close 会帮忙关闭流 - if (writer != null) { - writer.close(); - } - } - - // 方法2.1: 如果写到不同的sheet 同一个对象 使用 try-with-resources @since 3.1.0 + // 方法2: 如果写到不同的sheet 同一个对象 fileName = TestFileUtil.getPath() + "repeatedWrite" + System.currentTimeMillis() + ".xlsx"; // 这里 指定文件 try (ExcelWriter excelWriter = EasyExcel.write(fileName, DemoData.class).build()) { @@ -234,27 +198,7 @@ public class WriteTest { } } - // 方法2.2: 如果写到不同的sheet 同一个对象 不使用 try-with-resources - fileName = TestFileUtil.getPath() + "repeatedWrite" + System.currentTimeMillis() + ".xlsx"; - try { - // 这里 指定文件 - writer = EasyExcel.write(fileName, DemoData.class).build(); - // 去调用写入,这里我调用了五次,实际使用时根据数据库分页的总的页数来。这里最终会写到5个sheet里面 - for (int i = 0; i < 5; i++) { - // 每次都要创建writeSheet 这里注意必须指定sheetNo 而且sheetName必须不一样 - WriteSheet writeSheet = EasyExcel.writerSheet(i, "模板" + i).build(); - // 分页去数据库查询数据 这里可以去数据库查询每一页的数据 - List data = data(); - writer.write(data, writeSheet); - } - } finally { - // 千万别忘记close 会帮忙关闭流 - if (writer != null) { - writer.close(); - } - } - - // 方法3.1 如果写到不同的sheet 不同的对象 使用 try-with-resources @since 3.1.0 + // 方法3 如果写到不同的sheet 不同的对象 fileName = TestFileUtil.getPath() + "repeatedWrite" + System.currentTimeMillis() + ".xlsx"; // 这里 指定文件 try (ExcelWriter excelWriter = EasyExcel.write(fileName).build()) { @@ -269,26 +213,6 @@ public class WriteTest { } } - // 方法3.2 如果写到不同的sheet 不同的对象 不使用 try-with-resources - fileName = TestFileUtil.getPath() + "repeatedWrite" + System.currentTimeMillis() + ".xlsx"; - try { - // 这里 指定文件 - writer = EasyExcel.write(fileName).build(); - // 去调用写入,这里我调用了五次,实际使用时根据数据库分页的总的页数来。这里最终会写到5个sheet里面 - for (int i = 0; i < 5; i++) { - // 每次都要创建writeSheet 这里注意必须指定sheetNo 而且sheetName必须不一样。这里注意DemoData.class 可以每次都变,我这里为了方便 所以用的同一个class - // 实际上可以一直变 - WriteSheet writeSheet = EasyExcel.writerSheet(i, "模板" + i).head(DemoData.class).build(); - // 分页去数据库查询数据 这里可以去数据库查询每一页的数据 - List data = data(); - writer.write(data, writeSheet); - } - } finally { - // 千万别忘记close 会帮忙关闭流 - if (writer != null) { - writer.close(); - } - } } /** @@ -649,7 +573,7 @@ public class WriteTest { @Test public void tableWrite() { String fileName = TestFileUtil.getPath() + "tableWrite" + System.currentTimeMillis() + ".xlsx"; - // 方法1 这里直接写多个table的案例了,如果只有一个 也可以直一行代码搞定,参照其他案, 使用 try-with-resources @since 3.1.0 + // 方法1 这里直接写多个table的案例了,如果只有一个 也可以直一行代码搞定,参照其他案 // 这里 需要指定写用哪个class去写 try (ExcelWriter excelWriter = EasyExcel.write(fileName, DemoData.class).build()) { // 把sheet设置为不需要头 不然会输出sheet的头 这样看起来第一个table 就有2个头了 @@ -662,27 +586,6 @@ public class WriteTest { // 第二次写如也会创建头,然后在第一次的后面写入数据 excelWriter.write(data(), writeSheet, writeTable1); } - - // 方法2 这里直接写多个table的案例了,如果只有一个 也可以直一行代码搞定,参照其他案, 不使用 try-with-resources - // 这里 需要指定写用哪个class去写 - ExcelWriter excelWriter = null; - try { - excelWriter = EasyExcel.write(fileName, DemoData.class).build(); - // 把sheet设置为不需要头 不然会输出sheet的头 这样看起来第一个table 就有2个头了 - WriteSheet writeSheet = EasyExcel.writerSheet("模板").needHead(Boolean.FALSE).build(); - // 这里必须指定需要头,table 会继承sheet的配置,sheet配置了不需要,table 默认也是不需要 - WriteTable writeTable0 = EasyExcel.writerTable(0).needHead(Boolean.TRUE).build(); - WriteTable writeTable1 = EasyExcel.writerTable(1).needHead(Boolean.TRUE).build(); - // 第一次写入会创建头 - excelWriter.write(data(), writeSheet, writeTable0); - // 第二次写如也会创建头,然后在第一次的后面写入数据 - excelWriter.write(data(), writeSheet, writeTable1); - } finally { - // 千万别忘记close 会帮忙关闭流 - if (excelWriter != null) { - excelWriter.close(); - } - } } /** From 504fb7e90670cfeae46caeb4bbaa18330e149e1c Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 1 Jun 2022 19:39:58 +0800 Subject: [PATCH 05/68] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 101e4634..48a7e01d 100644 --- a/README.md +++ b/README.md @@ -16,9 +16,9 @@ EasyExcel [钉钉5群(已满): 32134498](https://h5.dingtalk.com/circle/healthCheckin.html?dtaction=os&corpId=dingb9fa1325d9dccc3ecac589edd02f1650&5233a=71a83&cbdbhh=qwertyuiop) [钉钉6群(已满): 34707941](https://h5.dingtalk.com/circle/healthCheckin.html?dtaction=os&corpId=dingcf68008a1d443ac012d5427bdb061b7a&6ae36c3d-0c80-4=22398493-6c2a-4&cbdbhh=qwertyuiop) [钉钉7群: 35235427](https://h5.dingtalk.com/circle/healthCheckin.html?dtaction=os&corpId=ding532b9018c06c7fc8660273c4b78e6440&167fb=ed003&cbdbhh=qwertyuiop) -[官方网站: https://yuque.com/easyexcel](https://www.yuque.com/easyexcel/doc/easyexcel) +[官方网站: https://easyexcel.opensource.alibaba.com/](https://easyexcel.opensource.alibaba.com/) -[常见问题](https://www.yuque.com/easyexcel/faq) +[常见问题](https://easyexcel.opensource.alibaba.com/qa/) #### 因为公司不方便用QQ,所以建议加钉钉群 # JAVA解析Excel工具EasyExcel From ebbb3387b8c9da40eb8a6aa4571b62ad961882f9 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 1 Jun 2022 19:43:23 +0800 Subject: [PATCH 06/68] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=96=87=E6=A1=A3?= =?UTF-8?q?=E5=9C=B0=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/ISSUE_TEMPLATE/bug.md | 2 +- .github/ISSUE_TEMPLATE/question.md | 2 +- .github/ISSUE_TEMPLATE/suggest.md | 2 +- README.md | 1 + 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md index 4ea8cee6..fde1de80 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -8,7 +8,7 @@ assignees: zhuangjiaju --- **建议先去看文档** -[快速开始](https://www.yuque.com/easyexcel/doc/easyexcel) 、[常见问题](https://www.yuque.com/easyexcel/faq) +[快速开始](https://easyexcel.opensource.alibaba.com/docs/current/) 、[常见问题](https://easyexcel.opensource.alibaba.com/qa/) **触发场景描述** **触发Bug的代码** diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md index 51cea2b3..78b4cf23 100644 --- a/.github/ISSUE_TEMPLATE/question.md +++ b/.github/ISSUE_TEMPLATE/question.md @@ -8,7 +8,7 @@ assignees: '' --- **建议先去看文档** -[快速开始](https://www.yuque.com/easyexcel/doc/easyexcel) 、[常见问题](https://www.yuque.com/easyexcel/faq) +[快速开始](https://easyexcel.opensource.alibaba.com/docs/current/) 、[常见问题](https://easyexcel.opensource.alibaba.com/qa/) **异常代码** ```java 这里写你的代码 diff --git a/.github/ISSUE_TEMPLATE/suggest.md b/.github/ISSUE_TEMPLATE/suggest.md index 1aeecd86..6b7402d2 100644 --- a/.github/ISSUE_TEMPLATE/suggest.md +++ b/.github/ISSUE_TEMPLATE/suggest.md @@ -8,5 +8,5 @@ assignees: '' --- **建议先去看文档** -[快速开始](https://www.yuque.com/easyexcel/doc/easyexcel) 、[常见问题](https://www.yuque.com/easyexcel/faq) +[快速开始](https://easyexcel.opensource.alibaba.com/docs/current/) 、[常见问题](https://easyexcel.opensource.alibaba.com/qa/) **建议描述** diff --git a/README.md b/README.md index 48a7e01d..f9801817 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ EasyExcel [钉钉5群(已满): 32134498](https://h5.dingtalk.com/circle/healthCheckin.html?dtaction=os&corpId=dingb9fa1325d9dccc3ecac589edd02f1650&5233a=71a83&cbdbhh=qwertyuiop) [钉钉6群(已满): 34707941](https://h5.dingtalk.com/circle/healthCheckin.html?dtaction=os&corpId=dingcf68008a1d443ac012d5427bdb061b7a&6ae36c3d-0c80-4=22398493-6c2a-4&cbdbhh=qwertyuiop) [钉钉7群: 35235427](https://h5.dingtalk.com/circle/healthCheckin.html?dtaction=os&corpId=ding532b9018c06c7fc8660273c4b78e6440&167fb=ed003&cbdbhh=qwertyuiop) + [官方网站: https://easyexcel.opensource.alibaba.com/](https://easyexcel.opensource.alibaba.com/) [常见问题](https://easyexcel.opensource.alibaba.com/qa/) From 72f2e24bf866d8237c55bd56f13616eb21f09bc8 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Thu, 2 Jun 2022 11:17:30 +0800 Subject: [PATCH 07/68] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8eafb40f..071815a4 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ EasyExcel Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析依然需要100M左右内存,改用easyexcel可以降低到几M,并且再大的excel也不会出现内存溢出;03版依赖POI的sax模式,在上层做了模型转换的封装,让使用者更加简单方便 ## 64M内存20秒读取75M(46W行25列)的Excel(3.0.2+版本) -当然还有极速模式能更快,但是内存占用会在100M多一点 +当然还有[极速模式](https://easyexcel.opensource.alibaba.com/qa/read#%E5%BC%80%E5%90%AF%E6%80%A5%E9%80%9F%E6%A8%A1%E5%BC%8F)能更快,但是内存占用会在100M多一点 ![img](img/readme/large.png) ## 关于版本选择 From 61c80a9ff2a12d6c180e3a9e14679f98ba959732 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 8 Jun 2022 17:38:09 +0800 Subject: [PATCH 08/68] =?UTF-8?q?*=20=E4=BF=AE=E5=A4=8D=E9=83=A8=E5=88=86x?= =?UTF-8?q?lsx=E6=97=A0=E6=B3=95=E8=AF=BB=E5=8F=96=E8=B6=85=E9=93=BE?= =?UTF-8?q?=E6=8E=A5=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- .../excel/analysis/v07/XlsxSaxAnalyser.java | 46 ++++++++++++++++-- .../v07/handlers/HyperlinkTagHandler.java | 31 ++++++++++-- .../excel/constant/ExcelXmlConstants.java | 5 ++ .../holder/xlsx/XlsxReadSheetHolder.java | 8 +++ .../holder/xlsx/XlsxReadWorkbookHolder.java | 6 +++ .../test/core/extra/ExtraDataTest.java | 44 ++++++++++++++++- .../resources/extra/extraRelationships.xlsx | Bin 0 -> 8826 bytes pom.xml | 4 +- update.md | 3 ++ 10 files changed, 136 insertions(+), 13 deletions(-) create mode 100644 easyexcel-test/src/test/resources/extra/extraRelationships.xlsx diff --git a/README.md b/README.md index 071815a4..649a114a 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都 com.alibaba easyexcel - 3.1.0 + 3.1.1 poi-ooxml-schemas diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java index 38918fb8..5104b1e3 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java @@ -8,6 +8,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.UUID; import javax.xml.parsers.ParserConfigurationException; @@ -25,17 +26,23 @@ import com.alibaba.excel.metadata.CellExtra; import com.alibaba.excel.read.metadata.ReadSheet; import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadWorkbookHolder; import com.alibaba.excel.util.FileUtils; +import com.alibaba.excel.util.MapUtils; import com.alibaba.excel.util.SheetUtils; import com.alibaba.excel.util.StringUtils; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.PackageAccess; import org.apache.poi.openxml4j.opc.PackagePart; +import org.apache.poi.openxml4j.opc.PackagePartName; +import org.apache.poi.openxml4j.opc.PackageRelationshipCollection; +import org.apache.poi.openxml4j.opc.PackagingURIHelper; import org.apache.poi.ss.util.CellAddress; import org.apache.poi.xssf.eventusermodel.XSSFReader; import org.apache.poi.xssf.model.CommentsTable; +import org.apache.poi.xssf.model.SharedStringsTable; import org.apache.poi.xssf.usermodel.XSSFComment; import org.apache.poi.xssf.usermodel.XSSFRelation; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook; @@ -52,6 +59,20 @@ import org.xml.sax.XMLReader; @Slf4j public class XlsxSaxAnalyser implements ExcelReadExecutor { + /** + * Storage sheet SharedStrings + */ + public static final PackagePartName SHARED_STRINGS_PART_NAME; + + static { + try { + SHARED_STRINGS_PART_NAME = PackagingURIHelper.createPartName("/xl/sharedStrings.xml"); + } catch (InvalidFormatException e) { + log.error("Initialize the XlsxSaxAnalyser failure", e); + throw new ExcelAnalysisException("Initialize the XlsxSaxAnalyser failure", e); + } + } + private final XlsxReadContext xlsxReadContext; private final List sheetList; private final Map sheetMap; @@ -68,11 +89,9 @@ public class XlsxSaxAnalyser implements ExcelReadExecutor { OPCPackage pkg = readOpcPackage(xlsxReadWorkbookHolder, decryptedStream); xlsxReadWorkbookHolder.setOpcPackage(pkg); - ArrayList packageParts = pkg.getPartsByContentType(XSSFRelation.SHARED_STRINGS.getContentType()); - - if (!CollectionUtils.isEmpty(packageParts)) { - PackagePart sharedStringsTablePackagePart = packageParts.get(0); - + // Read the Shared information Strings + PackagePart sharedStringsTablePackagePart = pkg.getPart(SHARED_STRINGS_PART_NAME); + if (sharedStringsTablePackagePart != null) { // Specify default cache defaultReadCache(xlsxReadWorkbookHolder, sharedStringsTablePackagePart); @@ -89,6 +108,9 @@ public class XlsxSaxAnalyser implements ExcelReadExecutor { sheetList = new ArrayList<>(); sheetMap = new HashMap<>(); commentsTableMap = new HashMap<>(); + Map packageRelationshipCollectionMap = MapUtils.newHashMap(); + xlsxReadWorkbookHolder.setPackageRelationshipCollectionMap(packageRelationshipCollectionMap); + XSSFReader.SheetIterator ite = (XSSFReader.SheetIterator)xssfReader.getSheetsData(); int index = 0; if (!ite.hasNext()) { @@ -104,6 +126,20 @@ public class XlsxSaxAnalyser implements ExcelReadExecutor { commentsTableMap.put(index, commentsTable); } } + if (xlsxReadContext.readWorkbookHolder().getExtraReadSet().contains(CellExtraTypeEnum.HYPERLINK)) { + PackageRelationshipCollection packageRelationshipCollection = Optional.ofNullable(ite.getSheetPart()) + .map(packagePart -> { + try { + return packagePart.getRelationships(); + } catch (InvalidFormatException e) { + log.warn("Reading the Relationship failed", e); + return null; + } + }).orElse(null); + if (packageRelationshipCollection != null) { + packageRelationshipCollectionMap.put(index, packageRelationshipCollection); + } + } index++; } } diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/HyperlinkTagHandler.java b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/HyperlinkTagHandler.java index ee0154e7..3f9e2ce7 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/HyperlinkTagHandler.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/HyperlinkTagHandler.java @@ -1,5 +1,9 @@ package com.alibaba.excel.analysis.v07.handlers; +import java.util.Optional; + +import org.apache.poi.openxml4j.opc.PackageRelationship; +import org.apache.poi.openxml4j.opc.PackageRelationshipCollection; import org.xml.sax.Attributes; import com.alibaba.excel.constant.ExcelXmlConstants; @@ -23,13 +27,32 @@ public class HyperlinkTagHandler extends AbstractXlsxTagHandler { @Override public void startElement(XlsxReadContext xlsxReadContext, String name, Attributes attributes) { String ref = attributes.getValue(ExcelXmlConstants.ATTRIBUTE_REF); - String location = attributes.getValue(ExcelXmlConstants.ATTRIBUTE_LOCATION); if (StringUtils.isEmpty(ref)) { return; } - CellExtra cellExtra = new CellExtra(CellExtraTypeEnum.HYPERLINK, location, ref); - xlsxReadContext.readSheetHolder().setCellExtra(cellExtra); - xlsxReadContext.analysisEventProcessor().extra(xlsxReadContext); + // Hyperlink has 2 case: + // case 1,In the 'location' tag + String location = attributes.getValue(ExcelXmlConstants.ATTRIBUTE_LOCATION); + if (location != null) { + CellExtra cellExtra = new CellExtra(CellExtraTypeEnum.HYPERLINK, location, ref); + xlsxReadContext.readSheetHolder().setCellExtra(cellExtra); + xlsxReadContext.analysisEventProcessor().extra(xlsxReadContext); + return; + } + // case 2, In the 'r:id' tag, Then go to 'PackageRelationshipCollection' to get inside + String rId = attributes.getValue(ExcelXmlConstants.ATTRIBUTE_RID); + PackageRelationshipCollection packageRelationshipCollection = xlsxReadContext.xlsxReadSheetHolder() + .getPackageRelationshipCollection(); + if (rId == null || packageRelationshipCollection == null) { + return; + } + Optional.ofNullable(packageRelationshipCollection.getRelationshipByID(rId)) + .map(PackageRelationship::getTargetURI) + .ifPresent(uri -> { + CellExtra cellExtra = new CellExtra(CellExtraTypeEnum.HYPERLINK, uri.toString(), ref); + xlsxReadContext.readSheetHolder().setCellExtra(cellExtra); + xlsxReadContext.analysisEventProcessor().extra(xlsxReadContext); + }); } } diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java b/easyexcel-core/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java index 38c20050..bfd319a2 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java @@ -49,6 +49,11 @@ public class ExcelXmlConstants { */ public static final String ATTRIBUTE_LOCATION = "location"; + /** + * rId attribute + */ + public static final String ATTRIBUTE_RID = "r:id"; + /** * Cell range split */ diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/xlsx/XlsxReadSheetHolder.java b/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/xlsx/XlsxReadSheetHolder.java index f4ed56e7..9fa9182d 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/xlsx/XlsxReadSheetHolder.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/xlsx/XlsxReadSheetHolder.java @@ -10,6 +10,7 @@ import com.alibaba.excel.read.metadata.holder.ReadWorkbookHolder; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; +import org.apache.poi.openxml4j.opc.PackageRelationshipCollection; /** * sheet holder @@ -36,9 +37,16 @@ public class XlsxReadSheetHolder extends ReadSheetHolder { * Formula for current label. */ private StringBuilder tempFormula; + /** + * excel Relationship + */ + private PackageRelationshipCollection packageRelationshipCollection; public XlsxReadSheetHolder(ReadSheet readSheet, ReadWorkbookHolder readWorkbookHolder) { super(readSheet, readWorkbookHolder); this.tagDeque = new LinkedList(); + packageRelationshipCollection + = ((XlsxReadWorkbookHolder)readWorkbookHolder).getPackageRelationshipCollectionMap().get( + readSheet.getSheetNo()); } } diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/xlsx/XlsxReadWorkbookHolder.java b/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/xlsx/XlsxReadWorkbookHolder.java index c5d78e0f..fbeaf048 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/xlsx/XlsxReadWorkbookHolder.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/xlsx/XlsxReadWorkbookHolder.java @@ -15,6 +15,7 @@ import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import org.apache.poi.openxml4j.opc.OPCPackage; +import org.apache.poi.openxml4j.opc.PackageRelationshipCollection; import org.apache.poi.xssf.model.StylesTable; import org.apache.poi.xssf.usermodel.XSSFCellStyle; @@ -51,6 +52,11 @@ public class XlsxReadWorkbookHolder extends ReadWorkbookHolder { */ private Map dataFormatDataCache; + /** + * excel Relationship, key: sheetNo value: PackageRelationshipCollection + */ + private Map packageRelationshipCollectionMap; + public XlsxReadWorkbookHolder(ReadWorkbook readWorkbook) { super(readWorkbook); this.saxParserFactoryName = readWorkbook.getXlsxSAXParserFactoryName(); diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/extra/ExtraDataTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/extra/ExtraDataTest.java index cf7418d5..4475d83c 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/extra/ExtraDataTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/extra/ExtraDataTest.java @@ -2,6 +2,7 @@ package com.alibaba.easyexcel.test.core.extra; import java.io.File; +import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.slf4j.Logger; @@ -9,10 +10,13 @@ import org.slf4j.LoggerFactory; import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.enums.CellExtraTypeEnum; +import com.alibaba.excel.metadata.CellExtra; +import com.alibaba.excel.read.listener.ReadListener; +import com.alibaba.fastjson.JSON; /** - * * @author Jiaju Zhuang */ public class ExtraDataTest { @@ -20,10 +24,13 @@ public class ExtraDataTest { private static File file03; private static File file07; + private static File extraRelationships; + @BeforeClass public static void init() { file03 = TestFileUtil.readFile("extra" + File.separator + "extra.xls"); file07 = TestFileUtil.readFile("extra" + File.separator + "extra.xlsx"); + extraRelationships = TestFileUtil.readFile("extra" + File.separator + "extraRelationships.xlsx"); } @Test @@ -36,6 +43,41 @@ public class ExtraDataTest { read(file03); } + @Test + public void t03Read() { + EasyExcel.read(extraRelationships, ExtraData.class, new ReadListener() { + @Override + public void invoke(Object data, AnalysisContext context) { + } + + @Override + public void doAfterAllAnalysed(AnalysisContext context) { + } + + @Override + public void extra(CellExtra extra, AnalysisContext context) { + LOGGER.info("extra data:{}", JSON.toJSONString(extra)); + switch (extra.getType()) { + case HYPERLINK: + if ("222222222".equals(extra.getText())) { + Assert.assertEquals(1, (int)extra.getRowIndex()); + Assert.assertEquals(0, (int)extra.getColumnIndex()); + } else if ("333333333333".equals(extra.getText())) { + Assert.assertEquals(1, (int)extra.getRowIndex()); + Assert.assertEquals(1, (int)extra.getColumnIndex()); + } else { + Assert.fail("Unknown hyperlink!"); + } + break; + default: + } + } + }) + .extraRead(CellExtraTypeEnum.HYPERLINK) + .sheet() + .doRead(); + } + private void read(File file) { EasyExcel.read(file, ExtraData.class, new ExtraDataListener()).extraRead(CellExtraTypeEnum.COMMENT) .extraRead(CellExtraTypeEnum.HYPERLINK).extraRead(CellExtraTypeEnum.MERGE).sheet().doRead(); diff --git a/easyexcel-test/src/test/resources/extra/extraRelationships.xlsx b/easyexcel-test/src/test/resources/extra/extraRelationships.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..5784cd8b6766e1fd6a8bc3759080ea2ec3c6ae33 GIT binary patch literal 8826 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 - 3.1.0 + 3.1.1 UTF-8 1.8 true @@ -145,7 +145,7 @@ com.alibaba fastjson - 1.2.78 + 2.0.6 org.springframework.boot diff --git a/update.md b/update.md index f2bb7a64..6944a0ee 100644 --- a/update.md +++ b/update.md @@ -1,3 +1,6 @@ +# 3.1.1 +* 修复部分xlsx无法读取超链接的bug + # 3.1.0 * 支持jdk17,去除cglib&asm依赖,改成重新拷贝一份 [Issue #2240](https://github.com/alibaba/easyexcel/issues/2240) * 升级ehcache 到 3.9.9 ,为了兼容jdk17 From dc65f43f01cba24797aa3311812db7767ee643ee Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 8 Jun 2022 17:42:39 +0800 Subject: [PATCH 09/68] =?UTF-8?q?=E4=BF=AE=E6=94=B9readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 50 +++----------------------------------------- abouteasyexcel.md | 53 ----------------------------------------------- 2 files changed, 3 insertions(+), 100 deletions(-) delete mode 100644 abouteasyexcel.md diff --git a/README.md b/README.md index 0dff1ea3..69ef6c82 100644 --- a/README.md +++ b/README.md @@ -29,63 +29,19 @@ Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都 当然还有[极速模式](https://easyexcel.opensource.alibaba.com/qa/read#%E5%BC%80%E5%90%AF%E6%80%A5%E9%80%9F%E6%A8%A1%E5%BC%8F)能更快,但是内存占用会在100M多一点 ![img](img/readme/large.png) -## 关于版本选择 -如果项目中没有使用过poi,且jdk版本在8-17之间,直接使用最新版本,别犹豫。以下表格适用于不满足以上2个情况的。 - -| 版本 | poi依赖版本 (支持范围) | jdk版本支持范围 | 备注 | -|--------------------|-----------------------|--------------|---------------------------------------------| -| 3.1.0+ | 4.1.2 (4.1.2 - 5.2.2) | jkd8 - jdk17 | 推荐使用,会更新的版本 | -| 3.0.0-beta1 - 3.0.5 | 4.1.2 (4.1.2 - 5.2.2) | jkd8 - jdk11 | 不推荐项目新引入此版本,除非超级严重bug,否则不再更新 | -| 2.0.0-beta1-2.2.11 | 3.17 (3.17 - 4.1.2) | jdk6 - jdk11 | 不推荐项目新引入此版本,除非是jdk6否则不推荐使用,除非超级严重bug,否则不再更新 | -| 1+版本 | 3.17 (3.17 - 4.1.2) | jdk6 - jdk11 | 不推荐项目新引入此版本,超级严重bug,也不再更新 | - -注意: 3+版本的的easyexcel,使用poi 5+版本时,需要手动排除:poi-ooxml-schemas,例如: -```xml - - com.alibaba - easyexcel - 3.1.1 - - - poi-ooxml-schemas - org.apache.poi - - - -``` - -### 关于版本升级 -* 不建议跨大版本升级 尤其跨2个大版本 -* 2+ 升级到 3+ 一些不兼容的地方 - * 使用了自定义拦截器去修改样式的会出问题(不会编译报错) - * 读的时候`invoke`里面抛出异常,不会再额外封装一层`ExcelAnalysisException` (不会编译报错) - * 样式等注解涉及到 `boolean` or 一些枚举 值的 有变动,新增默认值(会编译报错,注解改就行) -* 大版本升级后建议相关内容重新测试下 - ### 最新版本 ```xml com.alibaba easyexcel - 3.1.0 + 3.1.1 ``` -### easyexcel人员招募 -由于工作较忙,有意愿做开源的同学可以报名,主要负责群里回答&issue处理,当然也可以做一些PR. -由于开源没有任何物质回报,然后现在的维护同学也是课余时间维护的,所以想加入的同学需要持之以恒,而不是一时兴起. -要求如下: -* 有一定java编码能力 & 良好的编码习惯 -* 了解easyexcel 读&写的原理 -* 热爱开源项目 -* 能长期坚持的去做 -* 相对工作没那么忙 - ## 相关文档 -* [快速开始](https://www.yuque.com/easyexcel/doc/easyexcel) -* [关于软件](/abouteasyexcel.md) +* [快速开始](https://easyexcel.opensource.alibaba.com/docs/current/) * [更新记事](/update.md) -* [贡献代码](https://www.yuque.com/easyexcel/doc/contribute) +* [贡献代码](https://easyexcel.opensource.alibaba.com/community/contribute) ## 维护者 姬朋飞(玉霄)、庄家钜、怀宇 diff --git a/abouteasyexcel.md b/abouteasyexcel.md deleted file mode 100644 index 54a4e1fd..00000000 --- a/abouteasyexcel.md +++ /dev/null @@ -1,53 +0,0 @@ -# easyexcel要去解决的问题 - -## Excel读写时候内存溢出 - -虽然POI是目前使用最多的用来做excel解析的框架,但这个框架并不那么完美。大部分使用POI都是使用他的userModel模式。userModel的好处是上手容易使用简单,随便拷贝个代码跑一下,剩下就是写业务转换了,虽然转换也要写上百行代码,相对比较好理解。然而userModel模式最大的问题是在于非常大的内存消耗,一个几兆的文件解析要用掉上百兆的内存。现在很多应用采用这种模式,之所以还正常在跑一定是并发不大,并发上来后一定会OOM或者频繁的full gc。 - -## 其他开源框架使用复杂 - -对POI有过深入了解的估计才知道原来POI还有SAX模式。但SAX模式相对比较复杂,excel有03和07两种版本,两个版本数据存储方式截然不同,sax解析方式也各不一样。想要了解清楚这两种解析方式,才去写代码测试,估计两天时间是需要的。再加上即使解析完,要转换到自己业务模型还要很多繁琐的代码。总体下来感觉至少需要三天,由于代码复杂,后续维护成本巨大。 - -## 其他开源框架存在一些BUG修复不及时 - -由于我们的系统大多数都是大并发的情况下运行的,在大并发情况下,我们会发现poi存在一些bug,如果让POI团队修复估计遥遥无期了。所以我们在easyexcel对这些bug做了规避。 -如下一段报错就是在大并发情况下poi抛的一个异常。 -``` -Caused by: java.io.IOException: Could not create temporary directory '/home/admin/dio2o/.default/temp/poifiles' - at org.apache.poi.util.DefaultTempFileCreationStrategy.createTempDirectory(DefaultTempFileCreationStrategy.java:93) ~[poi-3.15.jar:3.15] - at org.apache.poi.util.DefaultTempFileCreationStrategy.createPOIFilesDirectory(DefaultTempFileCreationStrategy.java:82) ~[poi-3.15.jar:3.15] -``` -报错地方poi源码如下 -``` - private void createTempDirectory(File directory) throws IOException { - if (!(directory.exists() || directory.mkdirs()) || !directory.isDirectory()) { - throw new IOException("Could not create temporary directory '" + directory + "'"); - } - } -``` -仔细看代码容易明白如果在并发情况下,如果2个线程同时判断directory.exists()都 为false,但执行directory.mkdirs()如果一些线程优先执行完,另外一个线程就会返回false。最终 throw new IOException("Could not create temporary directory '" + directory + "'")。针对这个问题easyexcel在写文件时候首先创建了该临时目录,避免poi在并发创建时候引起不该有的报错。 - -## Excel格式分析格式分析 - -- xls是Microsoft Excel2007前excel的文件存储格式,实现原理是基于微软的ole db是微软com组件的一种实现,本质上也是一个微型数据库,由于微软的东西很多不开源,另外也已经被淘汰,了解它的细节意义不大,底层的编程都是基于微软的com组件去开发的。 -- xlsx是Microsoft Excel2007后excel的文件存储格式,实现是基于openXml和zip技术。这种存储简单,安全传输方便,同时处理数据也变的简单。 -- csv 我们可以理解为纯文本文件,可以被excel打开。他的格式非常简单,解析起来和解析文本文件一样。 - -## 核心原理 - -写有大量数据的xlsx文件时,POI为我们提供了SXSSFWorkBook类来处理,这个类的处理机制是当内存中的数据条数达到一个极限数量的时候就flush这部分数据,再依次处理余下的数据,这个在大多数场景能够满足需求。 -读有大量数据的文件时,使用WorkBook处理就不行了,因为POI对文件是先将文件中的cell读入内存,生成一个树的结构(针对Excel中的每个sheet,使用TreeMap存储sheet中的行)。如果数据量比较大,则同样会产生java.lang.OutOfMemoryError: Java heap space错误。POI官方推荐使用“XSSF and SAX(event API)”方式来解决。 -分析清楚POI后要解决OOM有3个关键。 - -### 1、文件解压文件读取通过文件形式 - -![屏幕快照 2018-01-22 上午8.52.08.png](http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/e3a3500014c95f7118d8c200a51acab4.png) - -### 2、避免将全部全部数据一次加载到内存 - -采用sax模式一行一行解析,并将一行的解析结果以观察者的模式通知处理。 -![基础模板1 (2).png](http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/82bb195ac62532963b2364d2e4da23e5.png) - -### 3、抛弃不重要的数据 - -Excel解析时候会包含样式,字体,宽度等数据,但这些数据是我们不关心的,如果将这部分数据抛弃可以大大降低内存使用。Excel中数据如下Style占了相当大的空间。 \ No newline at end of file From 887ef538139c8f76b1e2591f95532929c0461f31 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 8 Jun 2022 18:39:58 +0800 Subject: [PATCH 10/68] =?UTF-8?q?=E4=BF=AE=E6=94=B9pom=20name?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- easyexcel-core/pom.xml | 1 + easyexcel-support/pom.xml | 2 ++ easyexcel-test/pom.xml | 1 + easyexcel/pom.xml | 1 + 4 files changed, 5 insertions(+) diff --git a/easyexcel-core/pom.xml b/easyexcel-core/pom.xml index 4f03d716..d6e58002 100644 --- a/easyexcel-core/pom.xml +++ b/easyexcel-core/pom.xml @@ -13,6 +13,7 @@ jar easyexcel-core + easyexcel-core diff --git a/easyexcel-support/pom.xml b/easyexcel-support/pom.xml index d15b0d7a..db2dbd3f 100644 --- a/easyexcel-support/pom.xml +++ b/easyexcel-support/pom.xml @@ -13,6 +13,8 @@ jar easyexcel-support + easyexcel-support + diff --git a/easyexcel-test/pom.xml b/easyexcel-test/pom.xml index f802f249..80821db2 100644 --- a/easyexcel-test/pom.xml +++ b/easyexcel-test/pom.xml @@ -13,6 +13,7 @@ jar easyexcel-test + easyexcel-test true diff --git a/easyexcel/pom.xml b/easyexcel/pom.xml index 303f79ad..495552c0 100644 --- a/easyexcel/pom.xml +++ b/easyexcel/pom.xml @@ -13,6 +13,7 @@ jar easyexcel + easyexcel From ea640e518dacb265825946cf00692235ce81bdf8 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Thu, 30 Jun 2022 14:26:51 +0800 Subject: [PATCH 11/68] Update README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增群聊 --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 69ef6c82..e5b3295c 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,8 @@ EasyExcel [钉钉4群(已满): 33491624](https://qr.dingtalk.com/action/joingroup?code=v1,k1,V14Pb65Too70rQkEaJ9ohb6lZBZbtp6jIL/q9EWh9vA=&_dt_no_comment=1&origin=11) [钉钉5群(已满): 32134498](https://h5.dingtalk.com/circle/healthCheckin.html?dtaction=os&corpId=dingb9fa1325d9dccc3ecac589edd02f1650&5233a=71a83&cbdbhh=qwertyuiop) [钉钉6群(已满): 34707941](https://h5.dingtalk.com/circle/healthCheckin.html?dtaction=os&corpId=dingcf68008a1d443ac012d5427bdb061b7a&6ae36c3d-0c80-4=22398493-6c2a-4&cbdbhh=qwertyuiop) -[钉钉7群: 35235427](https://h5.dingtalk.com/circle/healthCheckin.html?dtaction=os&corpId=ding532b9018c06c7fc8660273c4b78e6440&167fb=ed003&cbdbhh=qwertyuiop) +[钉钉7群(已满): 35235427](https://h5.dingtalk.com/circle/healthCheckin.html?dtaction=os&corpId=ding532b9018c06c7fc8660273c4b78e6440&167fb=ed003&cbdbhh=qwertyuiop) +[钉钉8群: 44752220](https://h5.dingtalk.com/circle/healthCheckin.html?dtaction=os&corpId=dingea96808beee421693fd4ba7542d6e5da&0380092a-fa46=a6a40905-7951&cbdbhh=qwertyuiop) [官方网站: https://easyexcel.opensource.alibaba.com/](https://easyexcel.opensource.alibaba.com/) From b30f2fa12d2dcdba73e8a89af3f7bcfb8b05fbd7 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Tue, 30 Aug 2022 15:26:35 +0800 Subject: [PATCH 12/68] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e5b3295c..47956ff4 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ EasyExcel [QQ2群(已满): 1097936804](https://jq.qq.com/?_wv=1027&k=j5zEy6Xl) [QQ3群(已满): 453928496](https://qm.qq.com/cgi-bin/qm/qr?k=e2ULsA5A0GldhV2CXJ8sIbAyu9I6qqs7&jump_from=webapi) [QQ4群(已满): 496594404](https://qm.qq.com/cgi-bin/qm/qr?k=e_aVG1Q7gi0PJUBkbrUGAgbeO3kUEInK&jump_from=webapi) -[QQ5群: 203228638](https://jq.qq.com/?_wv=1027&k=m9kqpoV6) +[QQ5群: 451925680](https://jq.qq.com/?_wv=1027&k=BbLBIo9P) [钉钉1群(已满): 21960511](https://qr.dingtalk.com/action/joingroup?code=v1,k1,cchz6k12ci9B08NNqhNRFGXocNVHrZtW0kaOtTKg/Rk=&_dt_no_comment=1&origin=11) [钉钉2群(已满): 32796397](https://qr.dingtalk.com/action/joingroup?code=v1,k1,jyU9GtEuNU5S0QTyklqYcYJ8qDZtUuTPMM7uPZTS8Hs=&_dt_no_comment=1&origin=11) [钉钉3群(已满): 33797247](https://qr.dingtalk.com/action/joingroup?code=v1,k1,3UGlEScTGQaHpW2cIRo+gkxJ9EVZ5fz26M6nW3uFP30=&_dt_no_comment=1&origin=11) From 7f612f24f8d7c459fe6515ee798fb6d2da74a17f Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Fri, 28 Oct 2022 20:56:23 +0800 Subject: [PATCH 13/68] =?UTF-8?q?*=20=E4=BF=AE=E5=A4=8D=E9=95=BF=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E8=BF=90=E8=A1=8C=E4=BC=9A=E4=BA=A7=E7=94=9F=E5=A4=A7?= =?UTF-8?q?=E5=AF=B9=E8=B1=A1=E7=9A=84bug=20[Issue=20#2725](https://github?= =?UTF-8?q?.com/alibaba/easyexcel/issues/2725)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/alibaba/excel/util/FileUtils.java | 3 --- pom.xml | 2 +- update.md | 3 +++ 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/util/FileUtils.java b/easyexcel-core/src/main/java/com/alibaba/excel/util/FileUtils.java index 41a4be0e..bd2d340c 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/util/FileUtils.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/util/FileUtils.java @@ -58,11 +58,9 @@ public class FileUtils { // Create a temporary directory in advance File tempFile = new File(tempFilePrefix); createDirectory(tempFile); - tempFile.deleteOnExit(); // Initialize the cache directory File cacheFile = new File(cachePath); createDirectory(cacheFile); - cacheFile.deleteOnExit(); } /** @@ -160,7 +158,6 @@ public class FileUtils { File poiFilesPathFile = new File(poiFilesPath); createDirectory(poiFilesPathFile); TempFile.setTempFileCreationStrategy(new DefaultTempFileCreationStrategy(poiFilesPathFile)); - poiFilesPathFile.deleteOnExit(); } public static File createCacheTmpFile() { diff --git a/pom.xml b/pom.xml index d8676d5c..319a85e0 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ - 3.1.1 + 3.1.2 UTF-8 1.8 true diff --git a/update.md b/update.md index 6944a0ee..b326ca07 100644 --- a/update.md +++ b/update.md @@ -1,3 +1,6 @@ +# 3.1.2 +* 修复长时间运行会产生大对象的bug [Issue #2725](https://github.com/alibaba/easyexcel/issues/2725) + # 3.1.1 * 修复部分xlsx无法读取超链接的bug From e64e8084f076438733dcb702a55cbbdba30dc6ea Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Fri, 28 Oct 2022 21:22:10 +0800 Subject: [PATCH 14/68] =?UTF-8?q?*=20=E4=BF=AE=E5=A4=8D=E9=95=BF=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E8=BF=90=E8=A1=8C=E4=BC=9A=E4=BA=A7=E7=94=9F=E5=A4=A7?= =?UTF-8?q?=E5=AF=B9=E8=B1=A1=E7=9A=84bug=20[Issue=20#2725](https://github?= =?UTF-8?q?.com/alibaba/easyexcel/issues/2725)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 47956ff4..58018547 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都 com.alibaba easyexcel - 3.1.1 + 3.1.2 ``` From bd793c856773f5cea2d8a4ce992b976b0fc6e515 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Fri, 28 Oct 2022 21:24:12 +0800 Subject: [PATCH 15/68] =?UTF-8?q?*=20=E4=BF=AE=E5=A4=8D=E9=95=BF=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E8=BF=90=E8=A1=8C=E4=BC=9A=E4=BA=A7=E7=94=9F=E5=A4=A7?= =?UTF-8?q?=E5=AF=B9=E8=B1=A1=E7=9A=84bug=20[Issue=20#2725](https://github?= =?UTF-8?q?.com/alibaba/easyexcel/issues/2725)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/alibaba/excel/util/FileUtils.java | 1 + 1 file changed, 1 insertion(+) diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/util/FileUtils.java b/easyexcel-core/src/main/java/com/alibaba/excel/util/FileUtils.java index bd2d340c..881c1437 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/util/FileUtils.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/util/FileUtils.java @@ -58,6 +58,7 @@ public class FileUtils { // Create a temporary directory in advance File tempFile = new File(tempFilePrefix); createDirectory(tempFile); + tempFile.deleteOnExit(); // Initialize the cache directory File cacheFile = new File(cachePath); createDirectory(cacheFile); From 0d635644ba732ee70baa4d8dd0ee7d4a8101889a Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 16 Nov 2022 10:44:11 +0800 Subject: [PATCH 16/68] =?UTF-8?q?*=20=E6=8F=90=E4=BE=9Bxlsx=E5=85=BC?= =?UTF-8?q?=E5=AE=B9=E6=80=A7=EF=BC=9A=E5=85=BC=E5=AE=B9`sharedStrings.xml?= =?UTF-8?q?`=20=E5=AD=98=E5=82=A8=E5=9C=A8=20`x:t`=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- .../sax/SharedStringsTableHandler.java | 73 +++++++++++------- .../excel/constant/ExcelXmlConstants.java | 24 ++++++ .../core/compatibility/CompatibilityTest.java | 12 +++ .../src/test/resources/compatibility/t02.xlsx | Bin 0 -> 10366 bytes pom.xml | 2 +- 6 files changed, 84 insertions(+), 29 deletions(-) create mode 100644 easyexcel-test/src/test/resources/compatibility/t02.xlsx diff --git a/README.md b/README.md index 58018547..a9ac8647 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都 com.alibaba easyexcel - 3.1.2 + 3.1.3 ``` diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/sax/SharedStringsTableHandler.java b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/sax/SharedStringsTableHandler.java index f4514e43..83e92df3 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/sax/SharedStringsTableHandler.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/sax/SharedStringsTableHandler.java @@ -4,6 +4,7 @@ import org.xml.sax.Attributes; import org.xml.sax.helpers.DefaultHandler; import com.alibaba.excel.cache.ReadCache; +import com.alibaba.excel.constant.ExcelXmlConstants; /** * Sax read sharedStringsTable.xml @@ -11,12 +12,6 @@ import com.alibaba.excel.cache.ReadCache; * @author Jiaju Zhuang */ public class SharedStringsTableHandler extends DefaultHandler { - private static final String T_TAG = "t"; - private static final String SI_TAG = "si"; - /** - * Mac 2016 2017 will have this extra field to ignore - */ - private static final String RPH_TAG = "rPh"; /** * The final piece of data @@ -43,34 +38,58 @@ public class SharedStringsTableHandler extends DefaultHandler { @Override public void startElement(String uri, String localName, String name, Attributes attributes) { - if (T_TAG.equals(name)) { - currentElementData = null; - isTagt = true; - } else if (SI_TAG.equals(name)) { - currentData = null; - } else if (RPH_TAG.equals(name)) { - ignoreTagt = true; + if (name == null) { + return; + } + switch (name) { + case ExcelXmlConstants.SHAREDSTRINGS_T_TAG: + case ExcelXmlConstants.SHAREDSTRINGS_X_T_TAG: + currentElementData = null; + isTagt = true; + break; + case ExcelXmlConstants.SHAREDSTRINGS_SI_TAG: + case ExcelXmlConstants.SHAREDSTRINGS_X_SI_TAG: + currentData = null; + break; + case ExcelXmlConstants.SHAREDSTRINGS_RPH_TAG: + case ExcelXmlConstants.SHAREDSTRINGS_X_RPH_TAG: + ignoreTagt = true; + break; + default: + // ignore } } @Override public void endElement(String uri, String localName, String name) { - if (T_TAG.equals(name)) { - if (currentElementData != null) { + if (name == null) { + return; + } + switch (name) { + case ExcelXmlConstants.SHAREDSTRINGS_T_TAG: + case ExcelXmlConstants.SHAREDSTRINGS_X_T_TAG: + if (currentElementData != null) { + if (currentData == null) { + currentData = new StringBuilder(); + } + currentData.append(currentElementData); + } + isTagt = false; + break; + case ExcelXmlConstants.SHAREDSTRINGS_SI_TAG: + case ExcelXmlConstants.SHAREDSTRINGS_X_SI_TAG: if (currentData == null) { - currentData = new StringBuilder(); + readCache.put(null); + } else { + readCache.put(currentData.toString()); } - currentData.append(currentElementData); - } - isTagt = false; - } else if (SI_TAG.equals(name)) { - if (currentData == null) { - readCache.put(null); - } else { - readCache.put(currentData.toString()); - } - } else if (RPH_TAG.equals(name)) { - ignoreTagt = false; + break; + case ExcelXmlConstants.SHAREDSTRINGS_RPH_TAG: + case ExcelXmlConstants.SHAREDSTRINGS_X_RPH_TAG: + ignoreTagt = false; + break; + default: + // ignore } } diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java b/easyexcel-core/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java index bfd319a2..4f5c64dc 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java @@ -59,4 +59,28 @@ public class ExcelXmlConstants { */ public static final String CELL_RANGE_SPLIT = ":"; + // The following is a constant read the `SharedStrings.xml` + + /** + * text + * https://learn.microsoft.com/en-us/dotnet/api/documentformat.openxml.spreadsheet + * .text?redirectedfrom=MSDN&view=openxml-2.8.1 + */ + public static final String SHAREDSTRINGS_T_TAG = "t"; + public static final String SHAREDSTRINGS_X_T_TAG = "x:t"; + + /** + * SharedStringItem + * https://learn.microsoft.com/en-us/dotnet/api/documentformat.openxml.spreadsheet + * .sharedstringitem?redirectedfrom=MSDN&view=openxml-2.8.1 + */ + public static final String SHAREDSTRINGS_SI_TAG = "si"; + public static final String SHAREDSTRINGS_X_SI_TAG = "x:si"; + + /** + * Mac 2016 2017 will have this extra field to ignore + */ + public static final String SHAREDSTRINGS_RPH_TAG = "rPh"; + public static final String SHAREDSTRINGS_X_RPH_TAG = "x:rPh"; + } diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/compatibility/CompatibilityTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/compatibility/CompatibilityTest.java index 027aa54f..3844978f 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/compatibility/CompatibilityTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/compatibility/CompatibilityTest.java @@ -5,6 +5,7 @@ import java.util.Map; import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.excel.EasyExcel; +import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; import org.junit.Assert; @@ -30,4 +31,15 @@ public class CompatibilityTest { Map row1 = list.get(1); Assert.assertEquals("Q235(碳钢)", row1.get(0)); } + + @Test + public void t02() { + // Exist in `sharedStrings.xml` `x:t` start tag, need to be compatible + List> list = EasyExcel.read(TestFileUtil.getPath() + "compatibility/t02.xlsx").sheet() + .headRowNumber(0).doReadSync(); + log.info("data:{}", JSON.toJSONString(list)); + Assert.assertEquals(3, list.size()); + Map row2 = list.get(2); + Assert.assertEquals("1,2-戊二醇", row2.get(2)); + } } diff --git a/easyexcel-test/src/test/resources/compatibility/t02.xlsx b/easyexcel-test/src/test/resources/compatibility/t02.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..b8d755de85bec3cc84e39ae6c831e48f1a3ec485 GIT binary patch literal 10366 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 Iif6?C18ms(`v3p{ literal 0 HcmV?d00001 diff --git a/pom.xml b/pom.xml index 319a85e0..39ca4669 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ - 3.1.2 + 3.1.3 UTF-8 1.8 true From 5199f5d01808bde556be559be3b78c025c77a101 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 16 Nov 2022 10:45:19 +0800 Subject: [PATCH 17/68] =?UTF-8?q?*=20=E6=8F=90=E4=BE=9Bxlsx=E5=85=BC?= =?UTF-8?q?=E5=AE=B9=E6=80=A7=EF=BC=9A=E5=85=BC=E5=AE=B9`sharedStrings.xml?= =?UTF-8?q?`=20=E5=AD=98=E5=82=A8=E5=9C=A8=20`x:t`=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a9ac8647..292bac65 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,8 @@ EasyExcel [钉钉5群(已满): 32134498](https://h5.dingtalk.com/circle/healthCheckin.html?dtaction=os&corpId=dingb9fa1325d9dccc3ecac589edd02f1650&5233a=71a83&cbdbhh=qwertyuiop) [钉钉6群(已满): 34707941](https://h5.dingtalk.com/circle/healthCheckin.html?dtaction=os&corpId=dingcf68008a1d443ac012d5427bdb061b7a&6ae36c3d-0c80-4=22398493-6c2a-4&cbdbhh=qwertyuiop) [钉钉7群(已满): 35235427](https://h5.dingtalk.com/circle/healthCheckin.html?dtaction=os&corpId=ding532b9018c06c7fc8660273c4b78e6440&167fb=ed003&cbdbhh=qwertyuiop) -[钉钉8群: 44752220](https://h5.dingtalk.com/circle/healthCheckin.html?dtaction=os&corpId=dingea96808beee421693fd4ba7542d6e5da&0380092a-fa46=a6a40905-7951&cbdbhh=qwertyuiop) +[钉钉8群(已满): 44752220](https://h5.dingtalk.com/circle/healthCheckin.html?dtaction=os&corpId=dingea96808beee421693fd4ba7542d6e5da&0380092a-fa46=a6a40905-7951&cbdbhh=qwertyuiop) +[钉钉9群: 11045002277](https://h5.dingtalk.com/circle/healthCheckin.html?dtaction=os&corpId=dinge338d2215891c0459c13cd6b2cb108a6&6972d=b92f9&cbdbhh=qwertyuiop) [官方网站: https://easyexcel.opensource.alibaba.com/](https://easyexcel.opensource.alibaba.com/) From ef806d5a82b030bcde07c01a7618a70fd6e6c4f5 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 16 Nov 2022 10:46:02 +0800 Subject: [PATCH 18/68] =?UTF-8?q?*=20=E6=8F=90=E4=BE=9Bxlsx=E5=85=BC?= =?UTF-8?q?=E5=AE=B9=E6=80=A7=EF=BC=9A=E5=85=BC=E5=AE=B9`sharedStrings.xml?= =?UTF-8?q?`=20=E5=AD=98=E5=82=A8=E5=9C=A8=20`x:t`=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- update.md | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/update.md b/update.md index b326ca07..1650072f 100644 --- a/update.md +++ b/update.md @@ -1,10 +1,17 @@ +# 3.1.3 + +* 提供xlsx兼容性:兼容`sharedStrings.xml` 存储在 `x:t`标签 + # 3.1.2 + * 修复长时间运行会产生大对象的bug [Issue #2725](https://github.com/alibaba/easyexcel/issues/2725) # 3.1.1 + * 修复部分xlsx无法读取超链接的bug # 3.1.0 + * 支持jdk17,去除cglib&asm依赖,改成重新拷贝一份 [Issue #2240](https://github.com/alibaba/easyexcel/issues/2240) * 升级ehcache 到 3.9.9 ,为了兼容jdk17 * 在有样式没有数据的情况下也算空行 [Issue #2294](https://github.com/alibaba/easyexcel/issues/2294) @@ -20,24 +27,27 @@ * csv支持设置读写编码 [Issue #2404](https://github.com/alibaba/easyexcel/issues/2404) * 读写支持`try-with-resources`语法糖 - # 3.0.5 + * 修复`ReadListener` 转换异常不抛出的问题 # 3.0.4 + * 调整读写默认大小,防止大批量写的时候可能会full gc * `fill`的情况新增 `afterRowDispose`事件 # 3.0.3 + * 修复`HeadStyle`无效的bug # 3.0.2 + * 大幅提升读写性能 * 修复列宽注解没用的bug [Issue #2151](https://github.com/alibaba/easyexcel/issues/2151) * 修复`CellData`接收失败的的bug [Issue #2147](https://github.com/alibaba/easyexcel/issues/2147) - # 3.0.1 + * 升级到正式版 * 修复填充样式可能丢失的问题 [Issue #2124](https://github.com/alibaba/easyexcel/issues/2124) * 修复填充数据为空 可能NPE的bug @@ -45,7 +55,6 @@ * 修复样式可能超过最大限制的bug * 修复写入过慢的bug - # 3.0.0-beta3 * 修复导出浮点型数据可能精度异常的bug @@ -128,7 +137,8 @@ * 修复xls仅公式行 不读取的bug [Issue #1324](https://github.com/alibaba/easyexcel/issues/1324) * 修复xls直接读取第2页 `NPE` 的bug [Issue #1280](https://github.com/alibaba/easyexcel/issues/1280) * 修复填充的时候,最后一行中间有空行会创建失败的bug -* 修复`includeColumnIndexes`不包含第列 会无法导出数据的bug [Issue #1346](https://github.com/alibaba/easyexcel/issues/1346) +* 修复`includeColumnIndexes`不包含第列 + 会无法导出数据的bug [Issue #1346](https://github.com/alibaba/easyexcel/issues/1346) * 修复`@NumberFormat`注解转换double时可能会丢失精度 [Issue #1306](https://github.com/alibaba/easyexcel/issues/1306) # 2.2.3 @@ -145,11 +155,14 @@ * 发布正式版 * 修复第一行为空不会调用`invokeHeadMap`的bug [Issue #993](https://github.com/alibaba/easyexcel/issues/993) -* 当类的属性没有按照ExcelProperty的属性index顺序排序的时候,写数据出现错乱 [Issue #1046](https://github.com/alibaba/easyexcel/issues/1046) -* 新增支持自定义转换器 入参可以为空 实现`NullableObjectConverter` 即可 [Issue #1084](https://github.com/alibaba/easyexcel/issues/1084) +* +当类的属性没有按照ExcelProperty的属性index顺序排序的时候,写数据出现错乱 [Issue #1046](https://github.com/alibaba/easyexcel/issues/1046) +* 新增支持自定义转换器 入参可以为空 实现`NullableObjectConverter` + 即可 [Issue #1084](https://github.com/alibaba/easyexcel/issues/1084) * 修复xls丢失结束标记的情况下 会漏读最后一行 * 修复填充的时候 多次`forceNewRow` 空指针的bug [Issue #1201](https://github.com/alibaba/easyexcel/issues/1201) -* 修复`table`、`sheet`中创建的拦截器不执行`workbook`事件的bug [Issue #1202](https://github.com/alibaba/easyexcel/issues/1202) +* 修复`table`、`sheet`中创建的拦截器不执行`workbook` + 事件的bug [Issue #1202](https://github.com/alibaba/easyexcel/issues/1202) # 2.2.0-beta2 From 06ec9d8748fe02c5828ecace76904aed197fde23 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 16 Nov 2022 11:18:25 +0800 Subject: [PATCH 19/68] =?UTF-8?q?=E8=87=AA=E5=8A=A8=E5=8F=91=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yml | 48 +++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..6eb9b075 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,48 @@ +## +## Copyright 2009-2021 the original author or authors. +## +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## +# +#name: Publish package to the Maven Central Repository +# +#on: +# push: +# branches: +# - master +# tags: [ "*" ] +# +#jobs: +# publish: +# runs-on: ubuntu-latest +# steps: +# - uses: actions/checkout@v2 +# - name: Set up Maven Central Repository +# uses: actions/setup-java@v2 +# with: +# java-version: '8' +# distribution: 'adopt' +# server-id: ossrh +# server-username: MAVEN_USERNAME +# server-password: MAVEN_PASSWORD +# - id: install-secret-key +# name: Install gpg secret key +# run: | +# cat <(echo -e "${{ secrets.OSSRH_GPG_SECRET_KEY }}") | gpg --batch --import +# gpg --list-secret-keys --keyid-format LONG +# - name: Publish package +# env: +# MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} +# MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} +# run: mvn --batch-mode -Dgpg.passphrase=${{ secrets.OSSRH_GPG_SECRET_KEY_PASSWORD }} clean deploy +# From e80287855e55b0b09c7e8baab05784a6d6b074d1 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 16 Nov 2022 11:21:40 +0800 Subject: [PATCH 20/68] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=A4=87=E6=B3=A8?= =?UTF-8?q?=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/alibaba/excel/constant/ExcelXmlConstants.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java b/easyexcel-core/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java index 4f5c64dc..8d50c18d 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java @@ -63,16 +63,12 @@ public class ExcelXmlConstants { /** * text - * https://learn.microsoft.com/en-us/dotnet/api/documentformat.openxml.spreadsheet - * .text?redirectedfrom=MSDN&view=openxml-2.8.1 */ public static final String SHAREDSTRINGS_T_TAG = "t"; public static final String SHAREDSTRINGS_X_T_TAG = "x:t"; /** * SharedStringItem - * https://learn.microsoft.com/en-us/dotnet/api/documentformat.openxml.spreadsheet - * .sharedstringitem?redirectedfrom=MSDN&view=openxml-2.8.1 */ public static final String SHAREDSTRINGS_SI_TAG = "si"; public static final String SHAREDSTRINGS_X_SI_TAG = "x:si"; From 3643937dfbc5e3f294eaa619ef9844bf64f671b4 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 16 Nov 2022 14:17:23 +0800 Subject: [PATCH 21/68] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8F=91=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yml | 86 +++++++++++++++++------------------ pom.xml | 24 ++++++++++ 2 files changed, 66 insertions(+), 44 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6eb9b075..df177bd4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,48 +1,46 @@ -## -## Copyright 2009-2021 the original author or authors. -## -## Licensed under the Apache License, Version 2.0 (the "License"); -## you may not use this file except in compliance with the License. -## You may obtain a copy of the License at -## -## http://www.apache.org/licenses/LICENSE-2.0 -## -## Unless required by applicable law or agreed to in writing, software -## distributed under the License is distributed on an "AS IS" BASIS, -## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -## See the License for the specific language governing permissions and -## limitations under the License. -## # -#name: Publish package to the Maven Central Repository +# Copyright 2009-2021 the original author or authors. # -#on: -# push: -# branches: -# - master -# tags: [ "*" ] +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at # -#jobs: -# publish: -# runs-on: ubuntu-latest -# steps: -# - uses: actions/checkout@v2 -# - name: Set up Maven Central Repository -# uses: actions/setup-java@v2 -# with: -# java-version: '8' -# distribution: 'adopt' -# server-id: ossrh -# server-username: MAVEN_USERNAME -# server-password: MAVEN_PASSWORD -# - id: install-secret-key -# name: Install gpg secret key -# run: | -# cat <(echo -e "${{ secrets.OSSRH_GPG_SECRET_KEY }}") | gpg --batch --import -# gpg --list-secret-keys --keyid-format LONG -# - name: Publish package -# env: -# MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} -# MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} -# run: mvn --batch-mode -Dgpg.passphrase=${{ secrets.OSSRH_GPG_SECRET_KEY_PASSWORD }} clean deploy +# http://www.apache.org/licenses/LICENSE-2.0 # +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +name: Publish package to the Maven Central Repository + +on: + push: + tags: + - ** + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up Maven Central Repository + uses: actions/setup-java@v2 + with: + java-version: '8' + distribution: 'adopt' + server-id: ossrh + server-username: MAVEN_USERNAME + server-password: MAVEN_PASSWORD + - id: install-secret-key + name: Install gpg secret key + run: | + cat <(echo -e "${{ secrets.OSSRH_GPG_SECRET_KEY }}") | gpg --batch --import + gpg --list-secret-keys --keyid-format LONG + - name: Publish package + env: + MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} + MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} + run: mvn --batch-mode -Dgpg.passphrase=${{ secrets.OSSRH_GPG_SECRET_KEY_PASSWORD }} clean deploy \ No newline at end of file diff --git a/pom.xml b/pom.xml index 39ca4669..2625a4f3 100644 --- a/pom.xml +++ b/pom.xml @@ -229,6 +229,11 @@ flatten-maven-plugin 1.2.7 + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.13 + @@ -307,6 +312,13 @@ + + + + --pinentry-mode + loopback + + org.apache.maven.plugins @@ -389,6 +401,18 @@ + + + + org.sonatype.plugins + nexus-staging-maven-plugin + true + + ossrh + https://oss.sonatype.org/ + + + From dead426418dea2614abc6e8a03ea2d997e311e4f Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 16 Nov 2022 14:19:50 +0800 Subject: [PATCH 22/68] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8F=91=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index df177bd4..9701c680 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,7 +14,7 @@ # limitations under the License. # -name: Publish package to the Maven Central Repository +name: Publish to Maven on: push: From e624b1914041a1460fa566f2249bf53033c7452f Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 16 Nov 2022 14:21:47 +0800 Subject: [PATCH 23/68] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8F=91=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9701c680..86c3403a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -19,8 +19,7 @@ name: Publish to Maven on: push: tags: - - ** - + - * jobs: publish: runs-on: ubuntu-latest From d06feeefa2fb34c68d7d057f8d75a706b19a71e1 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 16 Nov 2022 14:23:46 +0800 Subject: [PATCH 24/68] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8F=91=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 86c3403a..36257815 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,8 +18,8 @@ name: Publish to Maven on: push: - tags: - - * + tags: [ "*" ] + jobs: publish: runs-on: ubuntu-latest From 00be5b1703ffdde40f2cc8a26185681c057cb0d0 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 16 Nov 2022 14:25:02 +0800 Subject: [PATCH 25/68] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8F=91=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 36257815..33b5bc44 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,7 +14,7 @@ # limitations under the License. # -name: Publish to Maven +name: Publish package to the Maven Central Repository on: push: From b8d53c14a6afb6d1b2c267569382cfae00e80c22 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 16 Nov 2022 14:56:08 +0800 Subject: [PATCH 26/68] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=89=93=E5=8C=85?= =?UTF-8?q?=E5=91=BD=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 33b5bc44..70ab157e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -42,4 +42,4 @@ jobs: env: MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} - run: mvn --batch-mode -Dgpg.passphrase=${{ secrets.OSSRH_GPG_SECRET_KEY_PASSWORD }} clean deploy \ No newline at end of file + run: mvn --batch-mode -Dgpg.passphrase=${{ secrets.OSSRH_GPG_SECRET_KEY_PASSWORD }} clean deploy -Dmaven.test.skip=false -Dmaven.javadoc.skip=false -Dgpg.skip=false \ No newline at end of file From d30f56d932944d32539062d70c97494ae4860e16 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 16 Nov 2022 15:52:55 +0800 Subject: [PATCH 27/68] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E5=8F=91=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 6 +++--- .github/workflows/release.yml | 30 ++++++++++++------------------ pom.xml | 2 +- 3 files changed, 16 insertions(+), 22 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 76e5b481..728e060e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,14 +30,14 @@ jobs: name: Test JDK ${{ matrix.java }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@main - name: Set up JDK - uses: actions/setup-java@v2 + uses: actions/setup-java@main with: java-version: ${{ matrix.java }} distribution: ${{ matrix.distribution }} - name: Cache Maven - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ~/.m2 key: m2 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 70ab157e..c2a75d2d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,22 +24,16 @@ jobs: publish: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Set up Maven Central Repository - uses: actions/setup-java@v2 + - name: Check out Git repository + uses: actions/checkout@main + - name: Install Java and Maven + uses: actions/setup-java@main with: - java-version: '8' - distribution: 'adopt' - server-id: ossrh - server-username: MAVEN_USERNAME - server-password: MAVEN_PASSWORD - - id: install-secret-key - name: Install gpg secret key - run: | - cat <(echo -e "${{ secrets.OSSRH_GPG_SECRET_KEY }}") | gpg --batch --import - gpg --list-secret-keys --keyid-format LONG - - name: Publish package - env: - MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} - MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} - run: mvn --batch-mode -Dgpg.passphrase=${{ secrets.OSSRH_GPG_SECRET_KEY_PASSWORD }} clean deploy -Dmaven.test.skip=false -Dmaven.javadoc.skip=false -Dgpg.skip=false \ No newline at end of file + java-version: 8 + - name: Release Maven package + uses: samuelmeuli/action-maven-publish@v1 + with: + gpg_private_key: ${{ secrets.gpg_private_key }} + gpg_passphrase: ${{ secrets.gpg_passphrase }} + nexus_username: ${{ secrets.nexus_username }} + nexus_password: ${{ secrets.nexus_password }} \ No newline at end of file diff --git a/pom.xml b/pom.xml index 2625a4f3..1c0b667d 100644 --- a/pom.xml +++ b/pom.xml @@ -410,7 +410,7 @@ ossrh https://oss.sonatype.org/ - + false From bb97c51dbc304617c4db542b9a849abc9e03bd27 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 16 Nov 2022 15:56:03 +0800 Subject: [PATCH 28/68] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E5=8F=91=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c2a75d2d..d845ae0f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -30,6 +30,7 @@ jobs: uses: actions/setup-java@main with: java-version: 8 + distribution: 'adopt' - name: Release Maven package uses: samuelmeuli/action-maven-publish@v1 with: From 139d9eede7c108ef2ea164a49262b2a29603f93d Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 16 Nov 2022 16:00:59 +0800 Subject: [PATCH 29/68] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E5=8F=91=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d845ae0f..757a6842 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -34,7 +34,8 @@ jobs: - name: Release Maven package uses: samuelmeuli/action-maven-publish@v1 with: - gpg_private_key: ${{ secrets.gpg_private_key }} - gpg_passphrase: ${{ secrets.gpg_passphrase }} - nexus_username: ${{ secrets.nexus_username }} - nexus_password: ${{ secrets.nexus_password }} \ No newline at end of file + gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} + gpg_passphrase: ${{ secrets.GPG_PASSPHRASE }} + nexus_username: ${{ secrets.NEXUS_USERNAME }} + nexus_password: ${{ secrets.NEXUS_PASSWORD }} + maven_args: -Dmaven.test.skip=false -Dmaven.javadoc.skip=false -Dgpg.skip=false \ No newline at end of file From c4db560cf7bda70e49aa30cc01e4af7ef8b92270 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 16 Nov 2022 16:09:46 +0800 Subject: [PATCH 30/68] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E6=8C=87=E5=AF=BC?= =?UTF-8?q?=E5=B7=A5=E5=8F=91=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 757a6842..b007fdbc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,6 +31,10 @@ jobs: with: java-version: 8 distribution: 'adopt' + server-id: sonatype-nexus-staging + server-username: ${{ secrets.NEXUS_USERNAME }} + server-password: ${{ secrets.NEXUS_PASSWORD }} + gpg-passphrase: ${{ secrets.GPG_PASSPHRASE }} - name: Release Maven package uses: samuelmeuli/action-maven-publish@v1 with: From 68d1ee0e01d51974a92313d51b84aaad3fe7a957 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 16 Nov 2022 16:24:50 +0800 Subject: [PATCH 31/68] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8F=91=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yml | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b007fdbc..5fef4211 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,8 +17,8 @@ name: Publish package to the Maven Central Repository on: - push: - tags: [ "*" ] + release: + types: [created] jobs: publish: @@ -31,15 +31,11 @@ jobs: with: java-version: 8 distribution: 'adopt' - server-id: sonatype-nexus-staging - server-username: ${{ secrets.NEXUS_USERNAME }} - server-password: ${{ secrets.NEXUS_PASSWORD }} - gpg-passphrase: ${{ secrets.GPG_PASSPHRASE }} + server-id: ossrh + server-username: MAVEN_USERNAME + server-password: MAVEN_PASSWORD - name: Release Maven package - uses: samuelmeuli/action-maven-publish@v1 - with: - gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} - gpg_passphrase: ${{ secrets.GPG_PASSPHRASE }} - nexus_username: ${{ secrets.NEXUS_USERNAME }} - nexus_password: ${{ secrets.NEXUS_PASSWORD }} - maven_args: -Dmaven.test.skip=false -Dmaven.javadoc.skip=false -Dgpg.skip=false \ No newline at end of file + run: mvn --batch-mode deploy + env: + MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} + MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} \ No newline at end of file From cd9873662d14dbfc602fc0f3ed01795b5d8ddd83 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 16 Nov 2022 16:28:10 +0800 Subject: [PATCH 32/68] =?UTF-8?q?=E7=BC=93=E5=AD=98maven=E6=96=B0=E5=A2=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5fef4211..0c60418f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -34,6 +34,12 @@ jobs: server-id: ossrh server-username: MAVEN_USERNAME server-password: MAVEN_PASSWORD + - name: Cache Maven + uses: actions/cache@v3 + with: + path: ~/.m2 + key: m2 + restore-keys: m2 - name: Release Maven package run: mvn --batch-mode deploy env: From 108e5c6baa7d3a5c5abfa584ee6a12b6374c69aa Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 16 Nov 2022 16:42:29 +0800 Subject: [PATCH 33/68] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8F=91=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 7 ++++--- .github/workflows/release.yml | 16 +++++++++++----- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 728e060e..69ba885a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,12 +36,13 @@ jobs: with: java-version: ${{ matrix.java }} distribution: ${{ matrix.distribution }} - - name: Cache Maven + - name: Cache local Maven m2 uses: actions/cache@v3 with: path: ~/.m2 - key: m2 - restore-keys: m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-m2 - name: Chmod run: chmod +x mvnw - name: Test with Maven diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0c60418f..63b20d27 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -34,14 +34,20 @@ jobs: server-id: ossrh server-username: MAVEN_USERNAME server-password: MAVEN_PASSWORD - - name: Cache Maven + - name: Cache local Maven m2 uses: actions/cache@v3 with: path: ~/.m2 - key: m2 - restore-keys: m2 - - name: Release Maven package - run: mvn --batch-mode deploy + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-m2 + - id: install-secret-key + name: Install GPG secret key + run: | + cat <(echo -e "${{ secrets.GPG_PRIVATE_KEY }}") | gpg --batch --import + - name: Publish package + run: | + mvn --batch-mode -Dgpg.passphrase=${{ secrets.GPG_PASSPHRASE }} clean deploy -Dmaven.test.skip=false -Dmaven.javadoc.skip=false -Dgpg.skip=false env: MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} \ No newline at end of file From 71613f874c1d5814130ac1cadfbd303f48680b2f Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 16 Nov 2022 16:50:58 +0800 Subject: [PATCH 34/68] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8F=91=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 63b20d27..d3958e79 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -44,7 +44,7 @@ jobs: - id: install-secret-key name: Install GPG secret key run: | - cat <(echo -e "${{ secrets.GPG_PRIVATE_KEY }}") | gpg --batch --import + cat <(echo -e "${{ secrets.GPG_PRIVATE_KEY }}") - name: Publish package run: | mvn --batch-mode -Dgpg.passphrase=${{ secrets.GPG_PASSPHRASE }} clean deploy -Dmaven.test.skip=false -Dmaven.javadoc.skip=false -Dgpg.skip=false From b77409c8b80d08f56a4f05354de81d289516d30a Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 16 Nov 2022 17:00:53 +0800 Subject: [PATCH 35/68] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8F=91=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 98 +++++++++++++++++------------------ .github/workflows/release.yml | 6 ++- 2 files changed, 53 insertions(+), 51 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 69ba885a..95ff72b6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,53 +1,53 @@ +## +## Copyright 2009-2021 the original author or authors. +## +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## # -# Copyright 2009-2021 the original author or authors. +#name: Java CI # -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at +#on: [push, pull_request] # -# http://www.apache.org/licenses/LICENSE-2.0 +#jobs: +# test: +# runs-on: ubuntu-latest +# strategy: +# matrix: +# java: [ 8, 11, 17] +# distribution: [ 'adopt' ] +# fail-fast: false +# max-parallel: 4 +# name: Test JDK ${{ matrix.java }} # -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -name: Java CI - -on: [push, pull_request] - -jobs: - test: - runs-on: ubuntu-latest - strategy: - matrix: - java: [ 8, 11, 17] - distribution: [ 'adopt' ] - fail-fast: false - max-parallel: 4 - name: Test JDK ${{ matrix.java }} - - steps: - - uses: actions/checkout@main - - name: Set up JDK - uses: actions/setup-java@main - with: - java-version: ${{ matrix.java }} - distribution: ${{ matrix.distribution }} - - name: Cache local Maven m2 - uses: actions/cache@v3 - with: - path: ~/.m2 - key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-m2 - - name: Chmod - run: chmod +x mvnw - - name: Test with Maven - run: ./mvnw test -B -Dmaven.test.skip=false - - name: Maven Build - run: ./mvnw install -B -V - - name: Java Doc - run: ./mvnw javadoc:javadoc +# steps: +# - uses: actions/checkout@main +# - name: Set up JDK +# uses: actions/setup-java@main +# with: +# java-version: ${{ matrix.java }} +# distribution: ${{ matrix.distribution }} +# - name: Cache local Maven m2 +# uses: actions/cache@v3 +# with: +# path: ~/.m2 +# key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} +# restore-keys: | +# ${{ runner.os }}-m2 +# - name: Chmod +# run: chmod +x mvnw +# - name: Test with Maven +# run: ./mvnw test -B -Dmaven.test.skip=false +# - name: Maven Build +# run: ./mvnw install -B -V +# - name: Java Doc +# run: ./mvnw javadoc:javadoc diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d3958e79..b2475e02 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,6 +16,8 @@ name: Publish package to the Maven Central Repository + + on: release: types: [created] @@ -44,10 +46,10 @@ jobs: - id: install-secret-key name: Install GPG secret key run: | - cat <(echo -e "${{ secrets.GPG_PRIVATE_KEY }}") + cat <(echo -e "${{ secrets.GPG_PRIVATE_KEY }}") | gpg --batch --import - name: Publish package run: | - mvn --batch-mode -Dgpg.passphrase=${{ secrets.GPG_PASSPHRASE }} clean deploy -Dmaven.test.skip=false -Dmaven.javadoc.skip=false -Dgpg.skip=false + mvn --batch-mode -Dgpg.passphrase=${{ secrets.GPG_PASSPHRASE }} clean deploy -Dmaven.test.skip=true -Dmaven.javadoc.skip=false -Dgpg.skip=false env: MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} \ No newline at end of file From 94a8c69ba784e7dc39a686e1e133e3f73fb87bdc Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 16 Nov 2022 17:08:29 +0800 Subject: [PATCH 36/68] =?UTF-8?q?=E5=AE=8C=E6=88=90=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8F=91=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 98 ++++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 95ff72b6..69ba885a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,53 +1,53 @@ -## -## Copyright 2009-2021 the original author or authors. -## -## Licensed under the Apache License, Version 2.0 (the "License"); -## you may not use this file except in compliance with the License. -## You may obtain a copy of the License at -## -## http://www.apache.org/licenses/LICENSE-2.0 -## -## Unless required by applicable law or agreed to in writing, software -## distributed under the License is distributed on an "AS IS" BASIS, -## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -## See the License for the specific language governing permissions and -## limitations under the License. -## # -#name: Java CI +# Copyright 2009-2021 the original author or authors. # -#on: [push, pull_request] +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at # -#jobs: -# test: -# runs-on: ubuntu-latest -# strategy: -# matrix: -# java: [ 8, 11, 17] -# distribution: [ 'adopt' ] -# fail-fast: false -# max-parallel: 4 -# name: Test JDK ${{ matrix.java }} +# http://www.apache.org/licenses/LICENSE-2.0 # -# steps: -# - uses: actions/checkout@main -# - name: Set up JDK -# uses: actions/setup-java@main -# with: -# java-version: ${{ matrix.java }} -# distribution: ${{ matrix.distribution }} -# - name: Cache local Maven m2 -# uses: actions/cache@v3 -# with: -# path: ~/.m2 -# key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} -# restore-keys: | -# ${{ runner.os }}-m2 -# - name: Chmod -# run: chmod +x mvnw -# - name: Test with Maven -# run: ./mvnw test -B -Dmaven.test.skip=false -# - name: Maven Build -# run: ./mvnw install -B -V -# - name: Java Doc -# run: ./mvnw javadoc:javadoc +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +name: Java CI + +on: [push, pull_request] + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + java: [ 8, 11, 17] + distribution: [ 'adopt' ] + fail-fast: false + max-parallel: 4 + name: Test JDK ${{ matrix.java }} + + steps: + - uses: actions/checkout@main + - name: Set up JDK + uses: actions/setup-java@main + with: + java-version: ${{ matrix.java }} + distribution: ${{ matrix.distribution }} + - name: Cache local Maven m2 + uses: actions/cache@v3 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-m2 + - name: Chmod + run: chmod +x mvnw + - name: Test with Maven + run: ./mvnw test -B -Dmaven.test.skip=false + - name: Maven Build + run: ./mvnw install -B -V + - name: Java Doc + run: ./mvnw javadoc:javadoc From d755f10ad089c6634cbfa54c9a1a65b01cc69307 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 16 Nov 2022 17:09:57 +0800 Subject: [PATCH 37/68] =?UTF-8?q?=E5=AE=8C=E6=88=90=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8F=91=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1c0b667d..96d7f698 100644 --- a/pom.xml +++ b/pom.xml @@ -410,7 +410,7 @@ ossrh https://oss.sonatype.org/ - false + true From 1086cb2fe630944c6fb2145ce632fcbe61d3dfc6 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 16 Nov 2022 17:54:47 +0800 Subject: [PATCH 38/68] =?UTF-8?q?=E5=AE=8C=E6=88=90=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8F=91=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 98 ++++++++++++++++++++-------------------- pom.xml | 2 +- 2 files changed, 50 insertions(+), 50 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 69ba885a..95ff72b6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,53 +1,53 @@ +## +## Copyright 2009-2021 the original author or authors. +## +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## # -# Copyright 2009-2021 the original author or authors. +#name: Java CI # -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at +#on: [push, pull_request] # -# http://www.apache.org/licenses/LICENSE-2.0 +#jobs: +# test: +# runs-on: ubuntu-latest +# strategy: +# matrix: +# java: [ 8, 11, 17] +# distribution: [ 'adopt' ] +# fail-fast: false +# max-parallel: 4 +# name: Test JDK ${{ matrix.java }} # -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -name: Java CI - -on: [push, pull_request] - -jobs: - test: - runs-on: ubuntu-latest - strategy: - matrix: - java: [ 8, 11, 17] - distribution: [ 'adopt' ] - fail-fast: false - max-parallel: 4 - name: Test JDK ${{ matrix.java }} - - steps: - - uses: actions/checkout@main - - name: Set up JDK - uses: actions/setup-java@main - with: - java-version: ${{ matrix.java }} - distribution: ${{ matrix.distribution }} - - name: Cache local Maven m2 - uses: actions/cache@v3 - with: - path: ~/.m2 - key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-m2 - - name: Chmod - run: chmod +x mvnw - - name: Test with Maven - run: ./mvnw test -B -Dmaven.test.skip=false - - name: Maven Build - run: ./mvnw install -B -V - - name: Java Doc - run: ./mvnw javadoc:javadoc +# steps: +# - uses: actions/checkout@main +# - name: Set up JDK +# uses: actions/setup-java@main +# with: +# java-version: ${{ matrix.java }} +# distribution: ${{ matrix.distribution }} +# - name: Cache local Maven m2 +# uses: actions/cache@v3 +# with: +# path: ~/.m2 +# key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} +# restore-keys: | +# ${{ runner.os }}-m2 +# - name: Chmod +# run: chmod +x mvnw +# - name: Test with Maven +# run: ./mvnw test -B -Dmaven.test.skip=false +# - name: Maven Build +# run: ./mvnw install -B -V +# - name: Java Doc +# run: ./mvnw javadoc:javadoc diff --git a/pom.xml b/pom.xml index 96d7f698..1c0b667d 100644 --- a/pom.xml +++ b/pom.xml @@ -410,7 +410,7 @@ ossrh https://oss.sonatype.org/ - true + false From ba2380f493c95fffca6137f6d09ad357b630af2f Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 16 Nov 2022 18:47:05 +0800 Subject: [PATCH 39/68] =?UTF-8?q?=E5=AE=8C=E6=88=90=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8F=91=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b2475e02..3051a057 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -36,10 +36,10 @@ jobs: server-id: ossrh server-username: MAVEN_USERNAME server-password: MAVEN_PASSWORD - - name: Cache local Maven m2 + - name: Cache local Maven repository uses: actions/cache@v3 with: - path: ~/.m2 + path: ~/.m2/repository key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: | ${{ runner.os }}-m2 From 8f4f37a939670ac91df27fd31f46609cb1f72b56 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 16 Nov 2022 18:49:28 +0800 Subject: [PATCH 40/68] =?UTF-8?q?=E5=AE=8C=E6=88=90=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8F=91=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 98 ++++++++++++++++++++-------------------- pom.xml | 2 +- 2 files changed, 50 insertions(+), 50 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 95ff72b6..cc68ecf9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,53 +1,53 @@ -## -## Copyright 2009-2021 the original author or authors. -## -## Licensed under the Apache License, Version 2.0 (the "License"); -## you may not use this file except in compliance with the License. -## You may obtain a copy of the License at -## -## http://www.apache.org/licenses/LICENSE-2.0 -## -## Unless required by applicable law or agreed to in writing, software -## distributed under the License is distributed on an "AS IS" BASIS, -## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -## See the License for the specific language governing permissions and -## limitations under the License. -## # -#name: Java CI +# Copyright 2009-2021 the original author or authors. # -#on: [push, pull_request] +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at # -#jobs: -# test: -# runs-on: ubuntu-latest -# strategy: -# matrix: -# java: [ 8, 11, 17] -# distribution: [ 'adopt' ] -# fail-fast: false -# max-parallel: 4 -# name: Test JDK ${{ matrix.java }} +# http://www.apache.org/licenses/LICENSE-2.0 # -# steps: -# - uses: actions/checkout@main -# - name: Set up JDK -# uses: actions/setup-java@main -# with: -# java-version: ${{ matrix.java }} -# distribution: ${{ matrix.distribution }} -# - name: Cache local Maven m2 -# uses: actions/cache@v3 -# with: -# path: ~/.m2 -# key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} -# restore-keys: | -# ${{ runner.os }}-m2 -# - name: Chmod -# run: chmod +x mvnw -# - name: Test with Maven -# run: ./mvnw test -B -Dmaven.test.skip=false -# - name: Maven Build -# run: ./mvnw install -B -V -# - name: Java Doc -# run: ./mvnw javadoc:javadoc +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +name: Java CI + +on: [push, pull_request] + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + java: [ 8, 11, 17] + distribution: [ 'adopt' ] + fail-fast: false + max-parallel: 4 + name: Test JDK ${{ matrix.java }} + + steps: + - uses: actions/checkout@main + - name: Set up JDK + uses: actions/setup-java@main + with: + java-version: ${{ matrix.java }} + distribution: ${{ matrix.distribution }} + - name: Cache local Maven repository + uses: actions/cache@v3 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-m2 + - name: Chmod + run: chmod +x mvnw + - name: Test with Maven + run: ./mvnw test -B -Dmaven.test.skip=false + - name: Maven Build + run: ./mvnw install -B -V + - name: Java Doc + run: ./mvnw javadoc:javadoc diff --git a/pom.xml b/pom.xml index 1c0b667d..96d7f698 100644 --- a/pom.xml +++ b/pom.xml @@ -410,7 +410,7 @@ ossrh https://oss.sonatype.org/ - false + true From 3e37e5a1316db968367008fb242abd6e4165c772 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 16 Nov 2022 18:52:52 +0800 Subject: [PATCH 41/68] =?UTF-8?q?=E5=AE=8C=E6=88=90=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8F=91=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- update.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/update.md b/update.md index 1650072f..bc18ccf1 100644 --- a/update.md +++ b/update.md @@ -1,6 +1,6 @@ # 3.1.3 -* 提供xlsx兼容性:兼容`sharedStrings.xml` 存储在 `x:t`标签 +* 提高xlsx兼容性:兼容`sharedStrings.xml` 存在 `x:t`标签的情况 # 3.1.2 From d04850c89eeac5b63ed2e7b2921798164539e334 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Thu, 22 Dec 2022 19:18:41 +0800 Subject: [PATCH 42/68] =?UTF-8?q?*=20=E6=8F=90=E9=AB=98xlsx=E8=AF=BB?= =?UTF-8?q?=E5=8F=96=E5=85=BC=E5=AE=B9=E6=80=A7=EF=BC=9A=E5=9C=A8=E5=AD=98?= =?UTF-8?q?=E5=9C=A8=E7=AC=AC=E4=B8=80=E8=A1=8C=E5=BE=88=E5=A4=9A=E7=A9=BA?= =?UTF-8?q?=E5=88=97=E7=9A=84=E6=83=85=E5=86=B5=E4=B8=8B=EF=BC=8C=E5=BF=BD?= =?UTF-8?q?=E7=95=A5=E7=A9=BA=E5=88=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- .../read/listener/ModelBuildEventListener.java | 12 ++---------- .../read/metadata/holder/ReadSheetHolder.java | 2 +- .../DefaultAnalysisEventProcessor.java | 13 +++++++++++++ .../core/compatibility/CompatibilityTest.java | 10 ++++++++++ .../src/test/resources/compatibility/t03.xlsx | Bin 0 -> 51563 bytes pom.xml | 2 +- update.md | 6 ++++++ 8 files changed, 34 insertions(+), 13 deletions(-) create mode 100644 easyexcel-test/src/test/resources/compatibility/t03.xlsx diff --git a/README.md b/README.md index 292bac65..f4671022 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都 com.alibaba easyexcel - 3.1.3 + 3.1.4 ``` diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java b/easyexcel-core/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java index 44f77513..a313acb3 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java @@ -25,14 +25,6 @@ import org.springframework.cglib.beans.BeanMap; */ public class ModelBuildEventListener implements IgnoreExceptionReadListener>> { - @Override - public void invokeHead(Map> cellDataMap, AnalysisContext context) { - if (context.readSheetHolder().getMaxDataHeadSize() == null - || context.readSheetHolder().getMaxDataHeadSize() < CollectionUtils.size(cellDataMap)) { - context.readSheetHolder().setMaxDataHeadSize(CollectionUtils.size(cellDataMap)); - } - } - @Override public void invoke(Map> cellDataMap, AnalysisContext context) { ReadSheetHolder readSheetHolder = context.readSheetHolder(); @@ -73,8 +65,8 @@ public class ModelBuildEventListener implements IgnoreExceptionReadListener 0) { return readSheetHolder.excelReadHeadProperty().getHeadMap().size(); } - if (readSheetHolder.getMaxDataHeadSize() != null) { - return readSheetHolder.getMaxDataHeadSize(); + if (readSheetHolder.getMaxNotEmptyDataHeadSize() != null) { + return readSheetHolder.getMaxNotEmptyDataHeadSize(); } return 0; } diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/ReadSheetHolder.java b/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/ReadSheetHolder.java index 197835ad..47957044 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/ReadSheetHolder.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/ReadSheetHolder.java @@ -65,7 +65,7 @@ public class ReadSheetHolder extends AbstractReadHolder { * Read the size of the largest head in sheet head data. * see https://github.com/alibaba/easyexcel/issues/2014 */ - private Integer maxDataHeadSize; + private Integer maxNotEmptyDataHeadSize; public ReadSheetHolder(ReadSheet readSheet, ReadWorkbookHolder readWorkbookHolder) { super(readSheet, readWorkbookHolder); diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/read/processor/DefaultAnalysisEventProcessor.java b/easyexcel-core/src/main/java/com/alibaba/excel/read/processor/DefaultAnalysisEventProcessor.java index 45edb7b7..642e71fb 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/read/processor/DefaultAnalysisEventProcessor.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/read/processor/DefaultAnalysisEventProcessor.java @@ -3,8 +3,11 @@ package com.alibaba.excel.read.processor; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; +import java.util.stream.Collectors; import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.HeadKindEnum; import com.alibaba.excel.enums.RowTypeEnum; import com.alibaba.excel.exception.ExcelAnalysisException; @@ -17,6 +20,8 @@ import com.alibaba.excel.read.metadata.property.ExcelReadHeadProperty; import com.alibaba.excel.util.ConverterUtils; import com.alibaba.excel.util.StringUtils; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.MapUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -111,6 +116,14 @@ public class DefaultAnalysisEventProcessor implements AnalysisEventProcessor { } private void buildHead(AnalysisContext analysisContext, Map> cellDataMap) { + // Rule out empty head, and then take the largest column + if (MapUtils.isNotEmpty(cellDataMap)) { + cellDataMap.entrySet() + .stream() + .filter(entry -> CellDataTypeEnum.EMPTY != entry.getValue().getType()) + .forEach(entry -> analysisContext.readSheetHolder().setMaxNotEmptyDataHeadSize(entry.getKey())); + } + if (!HeadKindEnum.CLASS.equals(analysisContext.currentReadHolder().excelReadHeadProperty().getHeadKind())) { return; } diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/compatibility/CompatibilityTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/compatibility/CompatibilityTest.java index 3844978f..3b0b525a 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/compatibility/CompatibilityTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/compatibility/CompatibilityTest.java @@ -42,4 +42,14 @@ public class CompatibilityTest { Map row2 = list.get(2); Assert.assertEquals("1,2-戊二醇", row2.get(2)); } + + @Test + public void t03() { + // Exist in `sharedStrings.xml` `x:t` start tag, need to be compatible + List> list = EasyExcel.read(TestFileUtil.getPath() + "compatibility/t03.xlsx").sheet().doReadSync(); + log.info("data:{}", JSON.toJSONString(list)); + Assert.assertEquals(1, list.size()); + Map row0 = list.get(0); + Assert.assertEquals(12, row0.size()); + } } diff --git a/easyexcel-test/src/test/resources/compatibility/t03.xlsx b/easyexcel-test/src/test/resources/compatibility/t03.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..3a31ef78ea37ca02b8c5cc34644917c6faf1350d GIT binary patch literal 51563 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 G>;D12qYx4R literal 0 HcmV?d00001 diff --git a/pom.xml b/pom.xml index 96d7f698..eca83ca2 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ - 3.1.3 + 3.1.4 UTF-8 1.8 true diff --git a/update.md b/update.md index bc18ccf1..2c698a0b 100644 --- a/update.md +++ b/update.md @@ -1,3 +1,7 @@ +# 3.1.4 + +* 提高xlsx读取兼容性:在存在第一行很多空列的情况下,忽略空列 + # 3.1.3 * 提高xlsx兼容性:兼容`sharedStrings.xml` 存在 `x:t`标签的情况 @@ -156,7 +160,9 @@ * 发布正式版 * 修复第一行为空不会调用`invokeHeadMap`的bug [Issue #993](https://github.com/alibaba/easyexcel/issues/993) * + 当类的属性没有按照ExcelProperty的属性index顺序排序的时候,写数据出现错乱 [Issue #1046](https://github.com/alibaba/easyexcel/issues/1046) + * 新增支持自定义转换器 入参可以为空 实现`NullableObjectConverter` 即可 [Issue #1084](https://github.com/alibaba/easyexcel/issues/1084) * 修复xls丢失结束标记的情况下 会漏读最后一行 From dedd35d146103a8b0ce642eef91ae2c2a144470f Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 4 Jan 2023 16:53:43 +0800 Subject: [PATCH 43/68] =?UTF-8?q?*=20=E6=8F=90=E9=AB=98xlsx=E8=AF=BB?= =?UTF-8?q?=E5=8F=96=E5=85=BC=E5=AE=B9=E6=80=A7=EF=BC=9A=E5=85=BC=E7=94=A8?= =?UTF-8?q?ns2=E5=BC=80=E5=A4=B4=E7=9A=84=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sax/SharedStringsTableHandler.java | 6 ++++++ .../v07/handlers/sax/XlsxRowHandler.java | 10 +++++++++- .../excel/constant/ExcelXmlConstants.java | 17 +++++++++++++++++ .../core/compatibility/CompatibilityTest.java | 16 ++++++++++++++-- .../src/test/resources/compatibility/t04.xlsx | Bin 0 -> 19182 bytes pom.xml | 2 +- update.md | 4 ++++ 7 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 easyexcel-test/src/test/resources/compatibility/t04.xlsx diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/sax/SharedStringsTableHandler.java b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/sax/SharedStringsTableHandler.java index 83e92df3..203db6c7 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/sax/SharedStringsTableHandler.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/sax/SharedStringsTableHandler.java @@ -44,15 +44,18 @@ public class SharedStringsTableHandler extends DefaultHandler { switch (name) { case ExcelXmlConstants.SHAREDSTRINGS_T_TAG: case ExcelXmlConstants.SHAREDSTRINGS_X_T_TAG: + case ExcelXmlConstants.SHAREDSTRINGS_NS2_T_TAG: currentElementData = null; isTagt = true; break; case ExcelXmlConstants.SHAREDSTRINGS_SI_TAG: case ExcelXmlConstants.SHAREDSTRINGS_X_SI_TAG: + case ExcelXmlConstants.SHAREDSTRINGS_NS2_SI_TAG: currentData = null; break; case ExcelXmlConstants.SHAREDSTRINGS_RPH_TAG: case ExcelXmlConstants.SHAREDSTRINGS_X_RPH_TAG: + case ExcelXmlConstants.SHAREDSTRINGS_NS2_RPH_TAG: ignoreTagt = true; break; default: @@ -68,6 +71,7 @@ public class SharedStringsTableHandler extends DefaultHandler { switch (name) { case ExcelXmlConstants.SHAREDSTRINGS_T_TAG: case ExcelXmlConstants.SHAREDSTRINGS_X_T_TAG: + case ExcelXmlConstants.SHAREDSTRINGS_NS2_T_TAG: if (currentElementData != null) { if (currentData == null) { currentData = new StringBuilder(); @@ -78,6 +82,7 @@ public class SharedStringsTableHandler extends DefaultHandler { break; case ExcelXmlConstants.SHAREDSTRINGS_SI_TAG: case ExcelXmlConstants.SHAREDSTRINGS_X_SI_TAG: + case ExcelXmlConstants.SHAREDSTRINGS_NS2_SI_TAG: if (currentData == null) { readCache.put(null); } else { @@ -86,6 +91,7 @@ public class SharedStringsTableHandler extends DefaultHandler { break; case ExcelXmlConstants.SHAREDSTRINGS_RPH_TAG: case ExcelXmlConstants.SHAREDSTRINGS_X_RPH_TAG: + case ExcelXmlConstants.SHAREDSTRINGS_NS2_RPH_TAG: ignoreTagt = false; break; default: diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/sax/XlsxRowHandler.java b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/sax/XlsxRowHandler.java index 61805cd5..7b48c8a6 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/sax/XlsxRowHandler.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/sax/XlsxRowHandler.java @@ -26,33 +26,41 @@ import org.xml.sax.helpers.DefaultHandler; @Slf4j public class XlsxRowHandler extends DefaultHandler { private final XlsxReadContext xlsxReadContext; - private static final Map XLSX_CELL_HANDLER_MAP = new HashMap(32); + private static final Map XLSX_CELL_HANDLER_MAP = new HashMap<>(64); static { CellFormulaTagHandler cellFormulaTagHandler = new CellFormulaTagHandler(); XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.CELL_FORMULA_TAG, cellFormulaTagHandler); XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_CELL_FORMULA_TAG, cellFormulaTagHandler); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.NS2_CELL_FORMULA_TAG, cellFormulaTagHandler); CellInlineStringValueTagHandler cellInlineStringValueTagHandler = new CellInlineStringValueTagHandler(); XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.CELL_INLINE_STRING_VALUE_TAG, cellInlineStringValueTagHandler); XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_CELL_INLINE_STRING_VALUE_TAG, cellInlineStringValueTagHandler); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.NS2_CELL_INLINE_STRING_VALUE_TAG, cellInlineStringValueTagHandler); CellTagHandler cellTagHandler = new CellTagHandler(); XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.CELL_TAG, cellTagHandler); XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_CELL_TAG, cellTagHandler); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.NS2_CELL_TAG, cellTagHandler); CellValueTagHandler cellValueTagHandler = new CellValueTagHandler(); XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.CELL_VALUE_TAG, cellValueTagHandler); XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_CELL_VALUE_TAG, cellValueTagHandler); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.NS2_CELL_VALUE_TAG, cellValueTagHandler); CountTagHandler countTagHandler = new CountTagHandler(); XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.DIMENSION_TAG, countTagHandler); XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_DIMENSION_TAG, countTagHandler); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.NS2_DIMENSION_TAG, countTagHandler); HyperlinkTagHandler hyperlinkTagHandler = new HyperlinkTagHandler(); XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.HYPERLINK_TAG, hyperlinkTagHandler); XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_HYPERLINK_TAG, hyperlinkTagHandler); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.NS2_HYPERLINK_TAG, hyperlinkTagHandler); MergeCellTagHandler mergeCellTagHandler = new MergeCellTagHandler(); XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.MERGE_CELL_TAG, mergeCellTagHandler); XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_MERGE_CELL_TAG, mergeCellTagHandler); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.NS2_MERGE_CELL_TAG, mergeCellTagHandler); RowTagHandler rowTagHandler = new RowTagHandler(); XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.ROW_TAG, rowTagHandler); XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_ROW_TAG, rowTagHandler); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.NS2_ROW_TAG, rowTagHandler); } public XlsxRowHandler(XlsxReadContext xlsxReadContext) { diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java b/easyexcel-core/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java index 8d50c18d..c1d33592 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java @@ -17,16 +17,28 @@ public class ExcelXmlConstants { public static final String HYPERLINK_TAG = "hyperlink"; public static final String X_DIMENSION_TAG = "x:dimension"; + public static final String NS2_DIMENSION_TAG = "ns2:dimension"; + public static final String X_ROW_TAG = "x:row"; + public static final String NS2_ROW_TAG = "ns2:row"; + public static final String X_CELL_FORMULA_TAG = "x:f"; + public static final String NS2_CELL_FORMULA_TAG = "ns2:f"; public static final String X_CELL_VALUE_TAG = "x:v"; + public static final String NS2_CELL_VALUE_TAG = "ns2:v"; + /** * When the data is "inlineStr" his tag is "t" */ public static final String X_CELL_INLINE_STRING_VALUE_TAG = "x:t"; + public static final String NS2_CELL_INLINE_STRING_VALUE_TAG = "ns2:t"; + public static final String X_CELL_TAG = "x:c"; + public static final String NS2_CELL_TAG = "ns2:c"; public static final String X_MERGE_CELL_TAG = "x:mergeCell"; + public static final String NS2_MERGE_CELL_TAG = "ns2:mergeCell"; public static final String X_HYPERLINK_TAG = "x:hyperlink"; + public static final String NS2_HYPERLINK_TAG = "ns2:hyperlink"; /** * s attribute @@ -66,17 +78,22 @@ public class ExcelXmlConstants { */ public static final String SHAREDSTRINGS_T_TAG = "t"; public static final String SHAREDSTRINGS_X_T_TAG = "x:t"; + public static final String SHAREDSTRINGS_NS2_T_TAG = "ns2:t"; + /** * SharedStringItem */ public static final String SHAREDSTRINGS_SI_TAG = "si"; public static final String SHAREDSTRINGS_X_SI_TAG = "x:si"; + public static final String SHAREDSTRINGS_NS2_SI_TAG = "ns2:si"; + /** * Mac 2016 2017 will have this extra field to ignore */ public static final String SHAREDSTRINGS_RPH_TAG = "rPh"; public static final String SHAREDSTRINGS_X_RPH_TAG = "x:rPh"; + public static final String SHAREDSTRINGS_NS2_RPH_TAG = "ns2:rPh"; } diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/compatibility/CompatibilityTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/compatibility/CompatibilityTest.java index 3b0b525a..eadfd0a8 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/compatibility/CompatibilityTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/compatibility/CompatibilityTest.java @@ -45,11 +45,23 @@ public class CompatibilityTest { @Test public void t03() { - // Exist in `sharedStrings.xml` `x:t` start tag, need to be compatible - List> list = EasyExcel.read(TestFileUtil.getPath() + "compatibility/t03.xlsx").sheet().doReadSync(); + // In the presence of the first line of a lot of null columns, ignore null columns + List> list = EasyExcel.read(TestFileUtil.getPath() + "compatibility/t03.xlsx").sheet() + .doReadSync(); log.info("data:{}", JSON.toJSONString(list)); Assert.assertEquals(1, list.size()); Map row0 = list.get(0); Assert.assertEquals(12, row0.size()); } + + @Test + public void t04() { + // Exist in `sheet1.xml` `ns2:t` start tag, need to be compatible + List> list = EasyExcel.read(TestFileUtil.getPath() + "compatibility/t04.xlsx").sheet() + .doReadSync(); + log.info("data:{}", JSON.toJSONString(list)); + Assert.assertEquals(56, list.size()); + Map row0 = list.get(0); + Assert.assertEquals("QQSJK28F152A012242S0081", row0.get(5)); + } } diff --git a/easyexcel-test/src/test/resources/compatibility/t04.xlsx b/easyexcel-test/src/test/resources/compatibility/t04.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..7c95d425ced10ab0b8644db40d68ac599f440608 GIT binary patch literal 19182 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 literal 0 HcmV?d00001 diff --git a/pom.xml b/pom.xml index eca83ca2..de5d0681 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ - 3.1.4 + 3.1.5 UTF-8 1.8 true diff --git a/update.md b/update.md index 2c698a0b..782e7a80 100644 --- a/update.md +++ b/update.md @@ -1,3 +1,7 @@ +# 3.1.5 + +* 提高xlsx读取兼容性:兼用ns2开头的标签 + # 3.1.4 * 提高xlsx读取兼容性:在存在第一行很多空列的情况下,忽略空列 From 5301198cd2120a5b32a38805a6c7db4ce5bfdbe0 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 4 Jan 2023 17:07:49 +0800 Subject: [PATCH 44/68] =?UTF-8?q?*=20=E6=8F=90=E9=AB=98xlsx=E8=AF=BB?= =?UTF-8?q?=E5=8F=96=E5=85=BC=E5=AE=B9=E6=80=A7=EF=BC=9A=E5=85=BC=E7=94=A8?= =?UTF-8?q?ns2=E5=BC=80=E5=A4=B4=E7=9A=84=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f4671022..ba2e8c34 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都 com.alibaba easyexcel - 3.1.4 + 3.1.5 ``` From 88b7aac08d72010da85e51dac48d1cec40b28b80 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Thu, 5 Jan 2023 21:11:42 +0800 Subject: [PATCH 45/68] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=AD=94=E7=96=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ba2e8c34..8c7763b3 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,8 @@ EasyExcel [QQ2群(已满): 1097936804](https://jq.qq.com/?_wv=1027&k=j5zEy6Xl) [QQ3群(已满): 453928496](https://qm.qq.com/cgi-bin/qm/qr?k=e2ULsA5A0GldhV2CXJ8sIbAyu9I6qqs7&jump_from=webapi) [QQ4群(已满): 496594404](https://qm.qq.com/cgi-bin/qm/qr?k=e_aVG1Q7gi0PJUBkbrUGAgbeO3kUEInK&jump_from=webapi) -[QQ5群: 451925680](https://jq.qq.com/?_wv=1027&k=BbLBIo9P) +[QQ5群(已满): 451925680](https://jq.qq.com/?_wv=1027&k=6VHhvxyf) +[QQ6群: 784741035](https://jq.qq.com/?_wv=1027&k=BbLBIo9P) [钉钉1群(已满): 21960511](https://qr.dingtalk.com/action/joingroup?code=v1,k1,cchz6k12ci9B08NNqhNRFGXocNVHrZtW0kaOtTKg/Rk=&_dt_no_comment=1&origin=11) [钉钉2群(已满): 32796397](https://qr.dingtalk.com/action/joingroup?code=v1,k1,jyU9GtEuNU5S0QTyklqYcYJ8qDZtUuTPMM7uPZTS8Hs=&_dt_no_comment=1&origin=11) [钉钉3群(已满): 33797247](https://qr.dingtalk.com/action/joingroup?code=v1,k1,3UGlEScTGQaHpW2cIRo+gkxJ9EVZ5fz26M6nW3uFP30=&_dt_no_comment=1&origin=11) @@ -17,12 +18,16 @@ EasyExcel [钉钉6群(已满): 34707941](https://h5.dingtalk.com/circle/healthCheckin.html?dtaction=os&corpId=dingcf68008a1d443ac012d5427bdb061b7a&6ae36c3d-0c80-4=22398493-6c2a-4&cbdbhh=qwertyuiop) [钉钉7群(已满): 35235427](https://h5.dingtalk.com/circle/healthCheckin.html?dtaction=os&corpId=ding532b9018c06c7fc8660273c4b78e6440&167fb=ed003&cbdbhh=qwertyuiop) [钉钉8群(已满): 44752220](https://h5.dingtalk.com/circle/healthCheckin.html?dtaction=os&corpId=dingea96808beee421693fd4ba7542d6e5da&0380092a-fa46=a6a40905-7951&cbdbhh=qwertyuiop) -[钉钉9群: 11045002277](https://h5.dingtalk.com/circle/healthCheckin.html?dtaction=os&corpId=dinge338d2215891c0459c13cd6b2cb108a6&6972d=b92f9&cbdbhh=qwertyuiop) +[钉钉9群(已满): 11045002277](https://h5.dingtalk.com/circle/healthCheckin.html?dtaction=os&corpId=dinge338d2215891c0459c13cd6b2cb108a6&6972d=b92f9&cbdbhh=qwertyuiop) +[钉钉10群: 27360019755](https://qr.dingtalk.com/action/joingroup?code=v1,k1,v25LHn2liWmrWUKlkhIzOTcK7s7onp/sZP8mO5oIYSs=&_dt_no_comment=1&origin=11) [官方网站: https://easyexcel.opensource.alibaba.com/](https://easyexcel.opensource.alibaba.com/) -[常见问题](https://easyexcel.opensource.alibaba.com/qa/) -#### 因为公司不方便用QQ,所以建议加钉钉群 +## 获取帮助 +* 加入钉钉或QQ群,看完公告可以获得帮助 +* 自己参照 [文档](https://easyexcel.opensource.alibaba.com/docs/current/) 去尝试自己解决 +* 上面文档的右下角有个`?`,在尝试过文档无法自助解决的情况下,可以寻求人工帮助 +* 开源不易,如果觉得EasyExcel对您的工作还是有帮助的话,请帮忙在右上角点个⭐,您的支持是使EasyExcel变得更好最大的动力 # JAVA解析Excel工具EasyExcel Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析依然需要100M左右内存,改用easyexcel可以降低到几M,并且再大的excel也不会出现内存溢出;03版依赖POI的sax模式,在上层做了模型转换的封装,让使用者更加简单方便 From 3b709baae250d37594903f35cefd1ff9071e12e6 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Thu, 5 Jan 2023 21:12:36 +0800 Subject: [PATCH 46/68] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=AD=94=E7=96=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8c7763b3..f184fe8f 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ EasyExcel ## 获取帮助 * 加入钉钉或QQ群,看完公告可以获得帮助 * 自己参照 [文档](https://easyexcel.opensource.alibaba.com/docs/current/) 去尝试自己解决 -* 上面文档的右下角有个`?`,在尝试过文档无法自助解决的情况下,可以寻求人工帮助 +* 上面文档的右下角有个`?`,在尝试过文档无法自助解决的情况下,可以寻求人工在线帮助 * 开源不易,如果觉得EasyExcel对您的工作还是有帮助的话,请帮忙在右上角点个⭐,您的支持是使EasyExcel变得更好最大的动力 # JAVA解析Excel工具EasyExcel From 5586b87a8c6a86a9049c6ad8f914527ab595f0da Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Thu, 5 Jan 2023 21:37:43 +0800 Subject: [PATCH 47/68] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=AD=94=E7=96=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f184fe8f..cde8f87a 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ EasyExcel [QQ3群(已满): 453928496](https://qm.qq.com/cgi-bin/qm/qr?k=e2ULsA5A0GldhV2CXJ8sIbAyu9I6qqs7&jump_from=webapi) [QQ4群(已满): 496594404](https://qm.qq.com/cgi-bin/qm/qr?k=e_aVG1Q7gi0PJUBkbrUGAgbeO3kUEInK&jump_from=webapi) [QQ5群(已满): 451925680](https://jq.qq.com/?_wv=1027&k=6VHhvxyf) -[QQ6群: 784741035](https://jq.qq.com/?_wv=1027&k=BbLBIo9P) +[QQ6群: 784741035](https://jq.qq.com/?_wv=1027&k=BbLBIo9P) [钉钉1群(已满): 21960511](https://qr.dingtalk.com/action/joingroup?code=v1,k1,cchz6k12ci9B08NNqhNRFGXocNVHrZtW0kaOtTKg/Rk=&_dt_no_comment=1&origin=11) [钉钉2群(已满): 32796397](https://qr.dingtalk.com/action/joingroup?code=v1,k1,jyU9GtEuNU5S0QTyklqYcYJ8qDZtUuTPMM7uPZTS8Hs=&_dt_no_comment=1&origin=11) [钉钉3群(已满): 33797247](https://qr.dingtalk.com/action/joingroup?code=v1,k1,3UGlEScTGQaHpW2cIRo+gkxJ9EVZ5fz26M6nW3uFP30=&_dt_no_comment=1&origin=11) @@ -18,8 +18,8 @@ EasyExcel [钉钉6群(已满): 34707941](https://h5.dingtalk.com/circle/healthCheckin.html?dtaction=os&corpId=dingcf68008a1d443ac012d5427bdb061b7a&6ae36c3d-0c80-4=22398493-6c2a-4&cbdbhh=qwertyuiop) [钉钉7群(已满): 35235427](https://h5.dingtalk.com/circle/healthCheckin.html?dtaction=os&corpId=ding532b9018c06c7fc8660273c4b78e6440&167fb=ed003&cbdbhh=qwertyuiop) [钉钉8群(已满): 44752220](https://h5.dingtalk.com/circle/healthCheckin.html?dtaction=os&corpId=dingea96808beee421693fd4ba7542d6e5da&0380092a-fa46=a6a40905-7951&cbdbhh=qwertyuiop) -[钉钉9群(已满): 11045002277](https://h5.dingtalk.com/circle/healthCheckin.html?dtaction=os&corpId=dinge338d2215891c0459c13cd6b2cb108a6&6972d=b92f9&cbdbhh=qwertyuiop) -[钉钉10群: 27360019755](https://qr.dingtalk.com/action/joingroup?code=v1,k1,v25LHn2liWmrWUKlkhIzOTcK7s7onp/sZP8mO5oIYSs=&_dt_no_comment=1&origin=11) +[钉钉9群(已满): 11045002277](https://h5.dingtalk.com/circle/healthCheckin.html?dtaction=os&corpId=dinge338d2215891c0459c13cd6b2cb108a6&6972d=b92f9&cbdbhh=qwertyuiop) +[钉钉10群: 27360019755](https://qr.dingtalk.com/action/joingroup?code=v1,k1,v25LHn2liWmrWUKlkhIzOTcK7s7onp/sZP8mO5oIYSs=&_dt_no_comment=1&origin=11) [官方网站: https://easyexcel.opensource.alibaba.com/](https://easyexcel.opensource.alibaba.com/) @@ -27,7 +27,7 @@ EasyExcel * 加入钉钉或QQ群,看完公告可以获得帮助 * 自己参照 [文档](https://easyexcel.opensource.alibaba.com/docs/current/) 去尝试自己解决 * 上面文档的右下角有个`?`,在尝试过文档无法自助解决的情况下,可以寻求人工在线帮助 -* 开源不易,如果觉得EasyExcel对您的工作还是有帮助的话,请帮忙在右上角点个⭐,您的支持是使EasyExcel变得更好最大的动力 +* 开源不易,如果觉得EasyExcel对您的工作还是有帮助的话,请帮忙在右上角点个⭐Star,您的支持是使EasyExcel变得更好最大的动力 # JAVA解析Excel工具EasyExcel Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析依然需要100M左右内存,改用easyexcel可以降低到几M,并且再大的excel也不会出现内存溢出;03版依赖POI的sax模式,在上层做了模型转换的封装,让使用者更加简单方便 From 765a89f7d705a9f0ce322344fc153c842bd5d600 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Fri, 6 Jan 2023 14:36:55 +0800 Subject: [PATCH 48/68] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=AD=94=E7=96=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cde8f87a..f30c3df0 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ EasyExcel ## 获取帮助 * 加入钉钉或QQ群,看完公告可以获得帮助 * 自己参照 [文档](https://easyexcel.opensource.alibaba.com/docs/current/) 去尝试自己解决 -* 上面文档的右下角有个`?`,在尝试过文档无法自助解决的情况下,可以寻求人工在线帮助 +* 上面文档的右下角有个`?`,在尝试过文档无法自助解决的情况下,可以点击人工支持 * 开源不易,如果觉得EasyExcel对您的工作还是有帮助的话,请帮忙在右上角点个⭐Star,您的支持是使EasyExcel变得更好最大的动力 # JAVA解析Excel工具EasyExcel From 9ca65038caf899cc9479b9bf5945bda2e50e13a3 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Fri, 13 Jan 2023 16:31:00 +0800 Subject: [PATCH 49/68] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=A1=88=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../easyexcel/test/demo/rare/WriteTest.java | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/rare/WriteTest.java diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/rare/WriteTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/rare/WriteTest.java new file mode 100644 index 00000000..a2384da6 --- /dev/null +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/rare/WriteTest.java @@ -0,0 +1,87 @@ +package com.alibaba.easyexcel.test.demo.rare; + +import java.io.File; +import java.util.Date; +import java.util.List; + +import com.alibaba.easyexcel.test.demo.write.DemoData; +import com.alibaba.easyexcel.test.util.TestFileUtil; +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.ExcelWriter; +import com.alibaba.excel.util.FileUtils; +import com.alibaba.excel.util.ListUtils; +import com.alibaba.excel.write.handler.WorkbookWriteHandler; +import com.alibaba.excel.write.handler.context.WorkbookWriteHandlerContext; +import com.alibaba.excel.write.metadata.WriteSheet; + +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.junit.Ignore; +import org.junit.Test; + +/** + * 记录一些不太常见的案例 + * + * @author Jiaju Zhuang + */ +@Ignore +@Slf4j +public class WriteTest { + + /** + * 压缩临时文件 + * 在导出Excel且格式为xlsx的时候会生成一个临时的xml文件,会比较大,再磁盘不太够的情况下,可以压缩。 + * 当然压缩式耗费性能的 + */ + @Test + public void compressedTemporaryFile() { + log.info("临时的xml存储在:{}", FileUtils.getPoiFilesPath()); + File file = TestFileUtil.createNewFile("rare/compressedTemporaryFile" + System.currentTimeMillis() + + ".xlsx"); + + // 这里 需要指定写用哪个class去写 + try (ExcelWriter excelWriter = EasyExcel.write(file, DemoData.class).registerWriteHandler( + new WorkbookWriteHandler() { + + /** + * 拦截Workbook创建完成事件 + * @param context + */ + @Override + public void afterWorkbookCreate(WorkbookWriteHandlerContext context) { + // 获取到Workbook对象 + Workbook workbook = context.getWriteWorkbookHolder().getWorkbook(); + // 只有SXSSFWorkbook模式才会生成临时文件 + if (workbook instanceof SXSSFWorkbook) { + SXSSFWorkbook sxssfWorkbook = (SXSSFWorkbook)workbook; + // 设置临时文件压缩,当然这个会浪费cpu性能 但是临时文件会变小 + sxssfWorkbook.setCompressTempFiles(true); + } + } + }).build()) { + // 这里注意 如果同一个sheet只要创建一次 + WriteSheet writeSheet = EasyExcel.writerSheet("模板").build(); + // 10万数据 确保有足够的空间 + for (int i = 0; i < 10000; i++) { + // 分页去数据库查询数据 这里可以去数据库查询每一页的数据 + List data = data(); + excelWriter.write(data, writeSheet); + } + log.info("写入完毕,开始准备迁移压缩文件。"); + } + } + + private List data() { + List list = ListUtils.newArrayList(); + for (int i = 0; i < 10; i++) { + DemoData data = new DemoData(); + data.setString("字符串" + i); + data.setDate(new Date()); + data.setDoubleData(0.56); + list.add(data); + } + return list; + } + +} From 54844d9c343f610e608cc20f8c78736305b59ea2 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Sat, 14 Jan 2023 17:32:22 +0800 Subject: [PATCH 50/68] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/sync2gitee.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .github/workflows/sync2gitee.yml diff --git a/.github/workflows/sync2gitee.yml b/.github/workflows/sync2gitee.yml new file mode 100644 index 00000000..4361c55c --- /dev/null +++ b/.github/workflows/sync2gitee.yml @@ -0,0 +1,26 @@ +# 通过 Github action, 在仓库的每一次 commit 后自动同步到 Gitee 上 +name: sync2gitee +on: + push: + branches: + - bugfix +jobs: + repo-sync: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@main + with: + persist-credentials: false + - name: sync github -> gitee + uses: Yikun/hub-mirror-action@master + with: + # 必选,需要同步的 Github 用户(源) + src: 'alibaba/easyexcel' + # 必选,需要同步到的 Gitee 用户(目的) + dst: 'easyexcel/easyexcel' + # 必选,Gitee公钥对应的私钥,https://gitee.com/profile/sshkeys + dst_key: ${{ secrets.GITEE_PRIVATE_KEY }} + # 必选,Gitee对应的用于创建仓库的token,https://gitee.com/profile/personal_access_tokens + dst_token: ${{ secrets.GITEE_TOKEN }} + # 如果是组织,指定组织即可,默认为用户 user + # account_type: org \ No newline at end of file From ef6624d3b6b5a3b6bbba56b4c47377981d0a50da Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Sat, 14 Jan 2023 17:36:14 +0800 Subject: [PATCH 51/68] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/sync2gitee.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/sync2gitee.yml b/.github/workflows/sync2gitee.yml index 4361c55c..6e3077f4 100644 --- a/.github/workflows/sync2gitee.yml +++ b/.github/workflows/sync2gitee.yml @@ -1,5 +1,5 @@ # 通过 Github action, 在仓库的每一次 commit 后自动同步到 Gitee 上 -name: sync2gitee +name: Mirror the Github organization repos to Gitee on: push: branches: @@ -11,13 +11,13 @@ jobs: - uses: actions/checkout@main with: persist-credentials: false - - name: sync github -> gitee + - name: Mirror the Github organization repos to Gitee. uses: Yikun/hub-mirror-action@master with: # 必选,需要同步的 Github 用户(源) - src: 'alibaba/easyexcel' + src: alibaba/easyexcel # 必选,需要同步到的 Gitee 用户(目的) - dst: 'easyexcel/easyexcel' + dst: easyexcel/easyexcel # 必选,Gitee公钥对应的私钥,https://gitee.com/profile/sshkeys dst_key: ${{ secrets.GITEE_PRIVATE_KEY }} # 必选,Gitee对应的用于创建仓库的token,https://gitee.com/profile/personal_access_tokens From 105cb1ad613440fca1d9bbdb90fdee75ed054920 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Sat, 14 Jan 2023 17:41:27 +0800 Subject: [PATCH 52/68] =?UTF-8?q?=E5=90=8C=E6=AD=A5=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/sync2gitee.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/sync2gitee.yml b/.github/workflows/sync2gitee.yml index 6e3077f4..7281f42c 100644 --- a/.github/workflows/sync2gitee.yml +++ b/.github/workflows/sync2gitee.yml @@ -23,4 +23,6 @@ jobs: # 必选,Gitee对应的用于创建仓库的token,https://gitee.com/profile/personal_access_tokens dst_token: ${{ secrets.GITEE_TOKEN }} # 如果是组织,指定组织即可,默认为用户 user - # account_type: org \ No newline at end of file + # account_type: org + # 直接取当前项目的仓库名 + static_list: "easyexcel" \ No newline at end of file From e4c404a5b2539424e217ac5db30c7c0994630e7f Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Sat, 14 Jan 2023 17:43:27 +0800 Subject: [PATCH 53/68] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/sync2gitee.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/sync2gitee.yml b/.github/workflows/sync2gitee.yml index 7281f42c..67a31456 100644 --- a/.github/workflows/sync2gitee.yml +++ b/.github/workflows/sync2gitee.yml @@ -1,9 +1,7 @@ # 通过 Github action, 在仓库的每一次 commit 后自动同步到 Gitee 上 name: Mirror the Github organization repos to Gitee -on: - push: - branches: - - bugfix +on: [push] + jobs: repo-sync: runs-on: ubuntu-latest From 5796f68392783d315a2bf6d48ae32a5f44bbfcbc Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Sat, 14 Jan 2023 17:47:34 +0800 Subject: [PATCH 54/68] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E6=9C=80=E5=90=8E?= =?UTF-8?q?=E7=9A=84=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/sync2gitee.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/sync2gitee.yml b/.github/workflows/sync2gitee.yml index 67a31456..5dd07000 100644 --- a/.github/workflows/sync2gitee.yml +++ b/.github/workflows/sync2gitee.yml @@ -1,6 +1,6 @@ # 通过 Github action, 在仓库的每一次 commit 后自动同步到 Gitee 上 name: Mirror the Github organization repos to Gitee -on: [push] +on: [ push ] jobs: repo-sync: @@ -12,15 +12,15 @@ jobs: - name: Mirror the Github organization repos to Gitee. uses: Yikun/hub-mirror-action@master with: - # 必选,需要同步的 Github 用户(源) - src: alibaba/easyexcel - # 必选,需要同步到的 Gitee 用户(目的) - dst: easyexcel/easyexcel + # 必选,需要同步的 Github 这里记住选择的是仓库 或者账号 而不是具体的项目 + src: github/alibaba + # 必选,需要同步到的 Gitee 这里记住选择的是仓库 或者账号 而不是具体的项目 + dst: gitee/easyexcel # 必选,Gitee公钥对应的私钥,https://gitee.com/profile/sshkeys dst_key: ${{ secrets.GITEE_PRIVATE_KEY }} # 必选,Gitee对应的用于创建仓库的token,https://gitee.com/profile/personal_access_tokens - dst_token: ${{ secrets.GITEE_TOKEN }} + dst_token: ${{ secrets.GITEE_TOKEN }} # 如果是组织,指定组织即可,默认为用户 user - # account_type: org - # 直接取当前项目的仓库名 + account_type: org + # 需要同步的仓库里面的项目 static_list: "easyexcel" \ No newline at end of file From 72d950c8cd75ab77f56ee387a8d5a9da5b3eedac Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Sat, 14 Jan 2023 17:59:53 +0800 Subject: [PATCH 55/68] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E6=9C=80=E5=90=8E?= =?UTF-8?q?=E7=9A=84=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/sync2gitee.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sync2gitee.yml b/.github/workflows/sync2gitee.yml index 5dd07000..cc88d581 100644 --- a/.github/workflows/sync2gitee.yml +++ b/.github/workflows/sync2gitee.yml @@ -1,6 +1,6 @@ # 通过 Github action, 在仓库的每一次 commit 后自动同步到 Gitee 上 name: Mirror the Github organization repos to Gitee -on: [ push ] +on: [push, pull_request] jobs: repo-sync: From 1843fe5111e3e390c61ce803ecff709d95d4df67 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Sat, 14 Jan 2023 18:38:41 +0800 Subject: [PATCH 56/68] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=A7=A3=E5=86=B3?= =?UTF-8?q?=E6=96=B9=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitee/ISSUE_TEMPLATE.zh-CN.md | 9 ++ README.md | 201 +++++++++++++++++++-------------- 2 files changed, 127 insertions(+), 83 deletions(-) create mode 100644 .gitee/ISSUE_TEMPLATE.zh-CN.md diff --git a/.gitee/ISSUE_TEMPLATE.zh-CN.md b/.gitee/ISSUE_TEMPLATE.zh-CN.md new file mode 100644 index 00000000..fb929a06 --- /dev/null +++ b/.gitee/ISSUE_TEMPLATE.zh-CN.md @@ -0,0 +1,9 @@ +**建议先去看文档** +[快速开始](https://easyexcel.opensource.alibaba.com/docs/current/) 、[常见问题](https://easyexcel.opensource.alibaba.com/qa/) +**异常代码** +```java + 这里写你的代码 +``` +**异常提示** +请提供完整的异常提示,记住是全部异常! +**建议描述** \ No newline at end of file diff --git a/README.md b/README.md index f30c3df0..58b71a12 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,64 @@ EasyExcel [![Maven central](https://maven-badges.herokuapp.com/maven-central/com.alibaba/easyexcel/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.alibaba/easyexcel) [![License](http://img.shields.io/:license-apache-brightgreen.svg)](http://www.apache.org/licenses/LICENSE-2.0.html) +# JAVA解析Excel工具 + +Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。 +easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析依然需要100M左右内存,改用easyexcel可以降低到几M,并且再大的excel也不会出现内存溢出;03版依赖POI的sax模式,在上层做了模型转换的封装,让使用者更加简单方便 + +# github地址 + +[https://github.com/alibaba/easyexcel](https://github.com/alibaba/easyexcel) + +# 官方网站 + +[https://easyexcel.opensource.alibaba.com/](https://easyexcel.opensource.alibaba.com/) + +# 64M内存20秒读取75M(46W行25列)的Excel(3.0.2+版本) + +当然还有[极速模式](https://easyexcel.opensource.alibaba.com/qa/read#%E5%BC%80%E5%90%AF%E6%80%A5%E9%80%9F%E6%A8%A1%E5%BC%8F) +能更快,但是内存占用会在100M多一点 +![img](img/readme/large.png) + +# 最新版本 + +```xml + + + com.alibaba + easyexcel + 3.1.5 + +``` + +# 帮忙点个⭐Star + +开源不易,如果觉得EasyExcel对您的工作还是有帮助的话,请帮忙在github star +的右上角点个⭐Star,您的支持是使EasyExcel变得更好最大的动力 + +# 如果获取帮助 + +## 优先建议自己通过文档来解决问题 + +* [快速开始](https://easyexcel.opensource.alibaba.com/docs/current/) +* [常见问题](https://easyexcel.opensource.alibaba.com/docs/qa/) +* [API](https://easyexcel.opensource.alibaba.com/docs/current/api/) + +## 其次建议通过`issues`来解决解决问题 + +可以尝试在以下2个链接搜索问题,如果不存在可以尝试创建`issue`。 + +* 去 [github](https://github.com/alibaba/easyexcel/issues) 搜索`issues` +* 去 [gitee](https://gitee.com/easyexcel/easyexcel/issues) 搜索`issues` + +通过 `issues` 解决问题,可以给后面遇到相同问题的同学查看,所以比较推荐这种方式。 +不管`github`、`gitee`都会定期有人回答您的问题,比较紧急可以在提完`issue`以后在钉钉群艾特群主并发送`issue`地址帮忙解决。 +`QQ` 公司不让用,有时候也会去看,但是核心肯定还是在钉钉。 + +## 也可以加入钉钉&QQ群来解决问题 + +加入钉钉或QQ群,看完公告可以获得帮助 。 +比较推荐钉钉群,`QQ` 公司不让用,当然QQ群也会有热心网友帮忙解决。 [QQ1群(已满): 662022184](https://jq.qq.com/?_wv=1027&k=1T21jJxh) [QQ2群(已满): 1097936804](https://jq.qq.com/?_wv=1027&k=j5zEy6Xl) [QQ3群(已满): 453928496](https://qm.qq.com/cgi-bin/qm/qr?k=e2ULsA5A0GldhV2CXJ8sIbAyu9I6qqs7&jump_from=webapi) @@ -19,110 +77,87 @@ EasyExcel [钉钉7群(已满): 35235427](https://h5.dingtalk.com/circle/healthCheckin.html?dtaction=os&corpId=ding532b9018c06c7fc8660273c4b78e6440&167fb=ed003&cbdbhh=qwertyuiop) [钉钉8群(已满): 44752220](https://h5.dingtalk.com/circle/healthCheckin.html?dtaction=os&corpId=dingea96808beee421693fd4ba7542d6e5da&0380092a-fa46=a6a40905-7951&cbdbhh=qwertyuiop) [钉钉9群(已满): 11045002277](https://h5.dingtalk.com/circle/healthCheckin.html?dtaction=os&corpId=dinge338d2215891c0459c13cd6b2cb108a6&6972d=b92f9&cbdbhh=qwertyuiop) -[钉钉10群: 27360019755](https://qr.dingtalk.com/action/joingroup?code=v1,k1,v25LHn2liWmrWUKlkhIzOTcK7s7onp/sZP8mO5oIYSs=&_dt_no_comment=1&origin=11) +[钉钉10群: 27360019755](https://qr.dingtalk.com/action/joingroup?code=v1,k1,v25LHn2liWmrWUKlkhIzOTcK7s7onp/sZP8mO5oIYSs=&_dt_no_comment=1&origin=11) -[官方网站: https://easyexcel.opensource.alibaba.com/](https://easyexcel.opensource.alibaba.com/) +# 维护者 -## 获取帮助 -* 加入钉钉或QQ群,看完公告可以获得帮助 -* 自己参照 [文档](https://easyexcel.opensource.alibaba.com/docs/current/) 去尝试自己解决 -* 上面文档的右下角有个`?`,在尝试过文档无法自助解决的情况下,可以点击人工支持 -* 开源不易,如果觉得EasyExcel对您的工作还是有帮助的话,请帮忙在右上角点个⭐Star,您的支持是使EasyExcel变得更好最大的动力 - -# JAVA解析Excel工具EasyExcel -Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析依然需要100M左右内存,改用easyexcel可以降低到几M,并且再大的excel也不会出现内存溢出;03版依赖POI的sax模式,在上层做了模型转换的封装,让使用者更加简单方便 +姬朋飞(玉霄)、庄家钜、怀宇 -## 64M内存20秒读取75M(46W行25列)的Excel(3.0.2+版本) -当然还有[极速模式](https://easyexcel.opensource.alibaba.com/qa/read#%E5%BC%80%E5%90%AF%E6%80%A5%E9%80%9F%E6%A8%A1%E5%BC%8F)能更快,但是内存占用会在100M多一点 -![img](img/readme/large.png) +# 快速开始 -### 最新版本 -```xml - - com.alibaba - easyexcel - 3.1.5 - -``` +## 读Excel -## 相关文档 -* [快速开始](https://easyexcel.opensource.alibaba.com/docs/current/) -* [更新记事](/update.md) -* [贡献代码](https://easyexcel.opensource.alibaba.com/community/contribute) - -## 维护者 -姬朋飞(玉霄)、庄家钜、怀宇 -## 快速开始 -### 读Excel DEMO代码地址:[https://github.com/alibaba/easyexcel/blob/master/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java](https://github.com/alibaba/easyexcel/blob/master/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java) ```java /** - * 最简单的读 - *

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

2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoDataListener} - *

3. 直接读即可 - */ - @Test - public void simpleRead() { - String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx"; - // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭 - EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).sheet().doRead(); + * 最简单的读 + *

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

2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoDataListener} + *

3. 直接读即可 + */ +@Test +public void simpleRead(){ + String fileName=TestFileUtil.getPath()+"demo"+File.separator+"demo.xlsx"; + // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭 + EasyExcel.read(fileName,DemoData.class,new DemoDataListener()).sheet().doRead(); } ``` -### 写Excel +## 写Excel + DEMO代码地址:[https://github.com/alibaba/easyexcel/blob/master/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java](https://github.com/alibaba/easyexcel/blob/master/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java) + ```java /** - * 最简单的写 - *

1. 创建excel对应的实体对象 参照{@link com.alibaba.easyexcel.test.demo.write.DemoData} - *

2. 直接写即可 - */ - @Test - public void simpleWrite() { - String fileName = TestFileUtil.getPath() + "write" + System.currentTimeMillis() + ".xlsx"; - // 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭 - // 如果这里想使用03 则 传入excelType参数即可 - EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(data()); + * 最简单的写 + *

1. 创建excel对应的实体对象 参照{@link com.alibaba.easyexcel.test.demo.write.DemoData} + *

2. 直接写即可 + */ +@Test +public void simpleWrite(){ + String fileName=TestFileUtil.getPath()+"write"+System.currentTimeMillis()+".xlsx"; + // 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭 + // 如果这里想使用03 则 传入excelType参数即可 + EasyExcel.write(fileName,DemoData.class).sheet("模板").doWrite(data()); } ``` -### web上传、下载 +## web上传、下载 + DEMO代码地址:[https://github.com/alibaba/easyexcel/blob/master/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java](https://github.com/alibaba/easyexcel/blob/master/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java) + ```java /** - * 文件下载(失败了会返回一个有部分数据的Excel) - *

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

- * 2. 设置返回的 参数 - *

- * 3. 直接写,这里注意,finish的时候会自动关闭OutputStream,当然你外面再关闭流问题不大 - */ - @GetMapping("download") - public void download(HttpServletResponse response) throws IOException { - // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman - response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); - response.setCharacterEncoding("utf-8"); - // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系 - String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20"); - response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); - EasyExcel.write(response.getOutputStream(), DownloadData.class).sheet("模板").doWrite(data()); + * 文件下载(失败了会返回一个有部分数据的Excel) + *

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

+ * 2. 设置返回的 参数 + *

+ * 3. 直接写,这里注意,finish的时候会自动关闭OutputStream,当然你外面再关闭流问题不大 + */ +@GetMapping("download") +public void download(HttpServletResponse response)throws IOException{ + // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系 + String fileName=URLEncoder.encode("测试","UTF-8").replaceAll("\\+","%20"); + response.setHeader("Content-disposition","attachment;filename*=utf-8''"+fileName+".xlsx"); + EasyExcel.write(response.getOutputStream(),DownloadData.class).sheet("模板").doWrite(data()); } - /** - * 文件上传 - *

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

2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link UploadDataListener} - *

3. 直接读即可 - */ - @PostMapping("upload") - @ResponseBody - public String upload(MultipartFile file) throws IOException { - EasyExcel.read(file.getInputStream(), UploadData.class, new UploadDataListener(uploadDAO)).sheet().doRead(); - return "success"; +/** + * 文件上传 + *

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

2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link UploadDataListener} + *

3. 直接读即可 + */ +@PostMapping("upload") +@ResponseBody +public String upload(MultipartFile file)throws IOException{ + EasyExcel.read(file.getInputStream(),UploadData.class,new UploadDataListener(uploadDAO)).sheet().doRead(); + return"success"; } -``` -### 联系我们 -有问题阿里同事可以通过钉钉找到我,阿里外同学可以通过git留言。其他技术非技术相关的也欢迎一起探讨。 +``` \ No newline at end of file From af6f5f78e884dd2a62daa874c3fefae437410cd5 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Sat, 14 Jan 2023 18:47:48 +0800 Subject: [PATCH 57/68] =?UTF-8?q?=E4=BF=AE=E6=94=B9readme=E6=96=87?= =?UTF-8?q?=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 112 +++++++++++++++++++++++++++--------------------------- 1 file changed, 57 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index 58b71a12..b77a4c67 100644 --- a/README.md +++ b/README.md @@ -37,9 +37,9 @@ easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析 # 帮忙点个⭐Star 开源不易,如果觉得EasyExcel对您的工作还是有帮助的话,请帮忙在github star -的右上角点个⭐Star,您的支持是使EasyExcel变得更好最大的动力 +的右上角点个⭐Star,您的支持是使EasyExcel变得更好最大的动力。 -# 如果获取帮助 +# 如何获取帮助 ## 优先建议自己通过文档来解决问题 @@ -87,77 +87,79 @@ easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析 ## 读Excel -DEMO代码地址:[https://github.com/alibaba/easyexcel/blob/master/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java](https://github.com/alibaba/easyexcel/blob/master/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java) +demo代码地址:[https://github.com/alibaba/easyexcel/blob/master/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java](https://github.com/alibaba/easyexcel/blob/master/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java) +详细文档地址:[https://easyexcel.opensource.alibaba.com/docs/current/quickstart/read](https://easyexcel.opensource.alibaba.com/docs/current/quickstart/read) ```java /** - * 最简单的读 - *

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

2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoDataListener} - *

3. 直接读即可 - */ -@Test -public void simpleRead(){ - String fileName=TestFileUtil.getPath()+"demo"+File.separator+"demo.xlsx"; - // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭 - EasyExcel.read(fileName,DemoData.class,new DemoDataListener()).sheet().doRead(); + * 最简单的读 + *

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

2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoDataListener} + *

3. 直接读即可 + */ + @Test + public void simpleRead() { + String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx"; + // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭 + EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).sheet().doRead(); } ``` ## 写Excel -DEMO代码地址:[https://github.com/alibaba/easyexcel/blob/master/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java](https://github.com/alibaba/easyexcel/blob/master/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java) +demo代码地址:[https://github.com/alibaba/easyexcel/blob/master/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java](https://github.com/alibaba/easyexcel/blob/master/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java) +详细文档地址:[https://easyexcel.opensource.alibaba.com/docs/current/quickstart/write](https://easyexcel.opensource.alibaba.com/docs/current/quickstart/write) ```java /** - * 最简单的写 - *

1. 创建excel对应的实体对象 参照{@link com.alibaba.easyexcel.test.demo.write.DemoData} - *

2. 直接写即可 - */ -@Test -public void simpleWrite(){ - String fileName=TestFileUtil.getPath()+"write"+System.currentTimeMillis()+".xlsx"; - // 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭 - // 如果这里想使用03 则 传入excelType参数即可 - EasyExcel.write(fileName,DemoData.class).sheet("模板").doWrite(data()); + * 最简单的写 + *

1. 创建excel对应的实体对象 参照{@link com.alibaba.easyexcel.test.demo.write.DemoData} + *

2. 直接写即可 + */ + @Test + public void simpleWrite() { + String fileName=TestFileUtil.getPath()+"write"+System.currentTimeMillis()+".xlsx"; + // 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭 + // 如果这里想使用03 则 传入excelType参数即可 + EasyExcel.write(fileName,DemoData.class).sheet("模板").doWrite(data()); } ``` ## web上传、下载 -DEMO代码地址:[https://github.com/alibaba/easyexcel/blob/master/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java](https://github.com/alibaba/easyexcel/blob/master/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java) +demo代码地址:[https://github.com/alibaba/easyexcel/blob/master/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java](https://github.com/alibaba/easyexcel/blob/master/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java) ```java - /** - * 文件下载(失败了会返回一个有部分数据的Excel) - *

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

- * 2. 设置返回的 参数 - *

- * 3. 直接写,这里注意,finish的时候会自动关闭OutputStream,当然你外面再关闭流问题不大 - */ -@GetMapping("download") -public void download(HttpServletResponse response)throws IOException{ - // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman - response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); - response.setCharacterEncoding("utf-8"); - // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系 - String fileName=URLEncoder.encode("测试","UTF-8").replaceAll("\\+","%20"); - response.setHeader("Content-disposition","attachment;filename*=utf-8''"+fileName+".xlsx"); - EasyExcel.write(response.getOutputStream(),DownloadData.class).sheet("模板").doWrite(data()); + /** + * 文件下载(失败了会返回一个有部分数据的Excel) + *

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

+ * 2. 设置返回的 参数 + *

+ * 3. 直接写,这里注意,finish的时候会自动关闭OutputStream,当然你外面再关闭流问题不大 + */ + @GetMapping("download") + public void download(HttpServletResponse response) throws IOException { + // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系 + String fileName=URLEncoder.encode("测试","UTF-8").replaceAll("\\+","%20"); + response.setHeader("Content-disposition","attachment;filename*=utf-8''"+fileName+".xlsx"); + EasyExcel.write(response.getOutputStream(),DownloadData.class).sheet("模板").doWrite(data()); } - -/** - * 文件上传 - *

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

2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link UploadDataListener} - *

3. 直接读即可 - */ -@PostMapping("upload") -@ResponseBody -public String upload(MultipartFile file)throws IOException{ - EasyExcel.read(file.getInputStream(),UploadData.class,new UploadDataListener(uploadDAO)).sheet().doRead(); - return"success"; + + /** + * 文件上传 + *

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

2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link UploadDataListener} + *

3. 直接读即可 + */ + @PostMapping("upload") + @ResponseBody + public String upload(MultipartFile file)throws IOException{ + EasyExcel.read(file.getInputStream(),UploadData.class,new UploadDataListener(uploadDAO)).sheet().doRead(); + return"success"; } ``` \ No newline at end of file From 1033a2514e0c3af8901d38f6fa6eeeedeede615f Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Sat, 14 Jan 2023 18:56:12 +0800 Subject: [PATCH 58/68] =?UTF-8?q?=E6=96=B0=E5=A2=9Egitee=E5=9C=B0=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index b77a4c67..38d5ba9e 100644 --- a/README.md +++ b/README.md @@ -9,13 +9,10 @@ EasyExcel Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。 easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析依然需要100M左右内存,改用easyexcel可以降低到几M,并且再大的excel也不会出现内存溢出;03版依赖POI的sax模式,在上层做了模型转换的封装,让使用者更加简单方便 -# github地址 - -[https://github.com/alibaba/easyexcel](https://github.com/alibaba/easyexcel) - -# 官方网站 - -[https://easyexcel.opensource.alibaba.com/](https://easyexcel.opensource.alibaba.com/) +# 网站 +* 官方网站:[https://easyexcel.opensource.alibaba.com/](https://easyexcel.opensource.alibaba.com/) +* github地址:[https://github.com/alibaba/easyexcel](https://github.com/alibaba/easyexcel) +* gitee地址:[https://gitee.com/easyexcel/easyexcel](https://gitee.com/easyexcel/easyexcel) # 64M内存20秒读取75M(46W行25列)的Excel(3.0.2+版本) From cd1d555137d7152e08514478d39b48dc2200ee20 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Sat, 14 Jan 2023 20:14:20 +0800 Subject: [PATCH 59/68] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=A8=A1=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitee/ISSUE_TEMPLATE.zh-CN.md | 2 +- .github/ISSUE_TEMPLATE/question.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitee/ISSUE_TEMPLATE.zh-CN.md b/.gitee/ISSUE_TEMPLATE.zh-CN.md index fb929a06..4fd09570 100644 --- a/.gitee/ISSUE_TEMPLATE.zh-CN.md +++ b/.gitee/ISSUE_TEMPLATE.zh-CN.md @@ -5,5 +5,5 @@ 这里写你的代码 ``` **异常提示** -请提供完整的异常提示,记住是全部异常! +大家尽量把问题一次性描述清楚,然后贴上全部异常,这样方便把问题一次性解决掉。 **建议描述** \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md index 78b4cf23..a3c4b4b3 100644 --- a/.github/ISSUE_TEMPLATE/question.md +++ b/.github/ISSUE_TEMPLATE/question.md @@ -14,5 +14,5 @@ assignees: '' 这里写你的代码 ``` **异常提示** -请提供完整的异常提示,记住是全部异常! +大家尽量把问题一次性描述清楚,然后贴上全部异常,这样方便把问题一次性解决掉。 **建议描述** From e58b1e4b116c7b72d72108b7ee2ed13a5bdad840 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Sat, 14 Jan 2023 20:16:04 +0800 Subject: [PATCH 60/68] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=A8=A1=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitee/ISSUE_TEMPLATE.zh-CN.md | 8 ++++---- .github/ISSUE_TEMPLATE/bug.md | 8 ++++---- .github/ISSUE_TEMPLATE/question.md | 8 ++++---- .github/ISSUE_TEMPLATE/suggest.md | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.gitee/ISSUE_TEMPLATE.zh-CN.md b/.gitee/ISSUE_TEMPLATE.zh-CN.md index 4fd09570..8d7f460f 100644 --- a/.gitee/ISSUE_TEMPLATE.zh-CN.md +++ b/.gitee/ISSUE_TEMPLATE.zh-CN.md @@ -1,9 +1,9 @@ -**建议先去看文档** +# 建议先去看文档 [快速开始](https://easyexcel.opensource.alibaba.com/docs/current/) 、[常见问题](https://easyexcel.opensource.alibaba.com/qa/) -**异常代码** +# 异常代码 ```java 这里写你的代码 ``` -**异常提示** +# 异常提示 大家尽量把问题一次性描述清楚,然后贴上全部异常,这样方便把问题一次性解决掉。 -**建议描述** \ No newline at end of file +# 其他描述 \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md index fde1de80..7ef28dd1 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -7,12 +7,12 @@ assignees: zhuangjiaju --- -**建议先去看文档** +# 建议先去看文档 [快速开始](https://easyexcel.opensource.alibaba.com/docs/current/) 、[常见问题](https://easyexcel.opensource.alibaba.com/qa/) -**触发场景描述** +# 触发场景描述 -**触发Bug的代码** +# 触发Bug的代码 ```java 这里写代码 ``` -**提示的异常或者没有达到的效果** +# 提示的异常或者没有达到的效果 diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md index a3c4b4b3..bd234cf8 100644 --- a/.github/ISSUE_TEMPLATE/question.md +++ b/.github/ISSUE_TEMPLATE/question.md @@ -7,12 +7,12 @@ assignees: '' --- -**建议先去看文档** +# 建议先去看文档 [快速开始](https://easyexcel.opensource.alibaba.com/docs/current/) 、[常见问题](https://easyexcel.opensource.alibaba.com/qa/) -**异常代码** +# 异常代码 ```java 这里写你的代码 ``` -**异常提示** +# 异常提示 大家尽量把问题一次性描述清楚,然后贴上全部异常,这样方便把问题一次性解决掉。 -**建议描述** +# 问题描述 diff --git a/.github/ISSUE_TEMPLATE/suggest.md b/.github/ISSUE_TEMPLATE/suggest.md index 6b7402d2..41884ceb 100644 --- a/.github/ISSUE_TEMPLATE/suggest.md +++ b/.github/ISSUE_TEMPLATE/suggest.md @@ -7,6 +7,6 @@ assignees: '' --- -**建议先去看文档** +# 建议先去看文档 [快速开始](https://easyexcel.opensource.alibaba.com/docs/current/) 、[常见问题](https://easyexcel.opensource.alibaba.com/qa/) -**建议描述** +# 建议描述 From f47fb7f36620e888f3ad38bdf818f45323579624 Mon Sep 17 00:00:00 2001 From: peggy Date: Mon, 16 Jan 2023 14:00:58 +0800 Subject: [PATCH 61/68] Update WriteTest.java MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 数据与表头不对应 --- .../java/com/alibaba/easyexcel/test/demo/write/WriteTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java index 607a91be..c3c15a3f 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java @@ -742,8 +742,8 @@ public class WriteTest { for (int i = 0; i < 10; i++) { List data = ListUtils.newArrayList(); data.add("字符串" + i); - data.add(new Date()); data.add(0.56); + data.add(new Date()); list.add(data); } return list; From 52a9df4c6aa225f643cca70b8da57055d5c586be Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Mon, 16 Jan 2023 20:39:21 +0800 Subject: [PATCH 62/68] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=8C=87=E5=AE=9A?= =?UTF-8?q?=E5=8D=95=E5=85=83=E6=A0=BC=E5=86=99=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../easyexcel/test/demo/rare/WriteTest.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/rare/WriteTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/rare/WriteTest.java index a2384da6..c35d7f96 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/rare/WriteTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/rare/WriteTest.java @@ -10,11 +10,18 @@ import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.util.FileUtils; import com.alibaba.excel.util.ListUtils; +import com.alibaba.excel.write.handler.RowWriteHandler; +import com.alibaba.excel.write.handler.SheetWriteHandler; import com.alibaba.excel.write.handler.WorkbookWriteHandler; +import com.alibaba.excel.write.handler.context.RowWriteHandlerContext; +import com.alibaba.excel.write.handler.context.SheetWriteHandlerContext; import com.alibaba.excel.write.handler.context.WorkbookWriteHandlerContext; import com.alibaba.excel.write.metadata.WriteSheet; import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.junit.Ignore; @@ -72,6 +79,55 @@ public class WriteTest { } } + /** + * 在指定单元格写入数据 + */ + @Test + public void specifiedCellWrite() { + File file = TestFileUtil.createNewFile("rare/specifiedCellWrite" + System.currentTimeMillis() + + ".xlsx"); + + // 需要区分是在 最后一行之前 还是之后 + // 区分的原因是:excel只能一直向前,而且内存里面只存储100条,而afterRowDispose是在每一行写入完成的时候调用,所以修改一行需要拦截这个事件 + // 如果是在最后一行之后,由于后面不会再有数据了,所以只要拦截afterWorkbookDispose,在整个excel快写完的时候调用,继续写入数据即可 + + EasyExcel.write(file, DemoData.class) + // 写入的值在最后一行之前 + .registerWriteHandler(new RowWriteHandler() { + @Override + public void afterRowDispose(RowWriteHandlerContext context) { + if (context.getRow().getRowNum() == 2) { + Cell cell = context.getRow().getCell(2); + if (cell == null) { + cell = context.getRow().createCell(2); + } + cell.setCellValue("测试的第二行数据呀"); + } + } + }) + // 写入的值 在最后一一行之后 + .registerWriteHandler(new WorkbookWriteHandler() { + @Override + public void afterWorkbookDispose(WorkbookWriteHandlerContext context) { + Workbook workbook = context.getWriteWorkbookHolder().getWorkbook(); + Sheet sheet = workbook.getSheetAt(0); + Row row = sheet.getRow(99); + if (row == null) { + row = sheet.createRow(99); + } + Cell cell = row.getCell(2); + if (cell == null) { + cell = row.createCell(2); + } + cell.setCellValue("测试地99行数据呀"); + } + }) + .sheet("模板") + .doWrite(data()); + + log.info("写入到文件完成:{}", file); + } + private List data() { List list = ListUtils.newArrayList(); for (int i = 0; i < 10; i++) { From a8814dcdccfd135d54aea8e9dbcc1a9df5200f84 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Tue, 17 Jan 2023 10:53:26 +0800 Subject: [PATCH 63/68] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=BA=BA=E5=91=98?= =?UTF-8?q?=E6=8B=9B=E8=81=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/README.md b/README.md index 38d5ba9e..960ec63e 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,33 @@ easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析 开源不易,如果觉得EasyExcel对您的工作还是有帮助的话,请帮忙在github star 的右上角点个⭐Star,您的支持是使EasyExcel变得更好最大的动力。 +# 人员招聘 + +由于工作较忙,需要招聘一些同学加入`EasyExcel`开源,一起跟着`EasyExcel`成长。 + +## 你将获得 + +* 认识一帮热爱开源的小伙伴 +* 你写的代码可以被无数人看到,提升自我编码能力 +* 可能会有一定的物质奖励(在和公司申请,不一定能过) + +## 你的工作 + +* 群&`issue`答疑 +* 做一些代码的`PR`合并去修复bug +* 讨论`EasyExcel`规划 + +## 招聘要求 + +* 3年以上Java编程经验,基础扎实 +* 对技术比较热爱,并且喜欢阅读源码 +* 自驱力强,能主动的研究一些问题 +* 需要持之以恒,开源需要长期维护 + +## 联系方式 + +直接加钉钉群,联系是仪即可 + # 如何获取帮助 ## 优先建议自己通过文档来解决问题 From 2a17919caabd8cf257be31b43f91bc94252f8fb1 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 18 Jan 2023 11:02:29 +0800 Subject: [PATCH 64/68] =?UTF-8?q?=E6=B5=8B=E8=AF=95big?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../analysis/v07/handlers/CellTagHandler.java | 2 +- .../easyexcel/test/temp/Lock2Test.java | 221 ++++++++++++++++-- 2 files changed, 207 insertions(+), 16 deletions(-) diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java index ce84d5e2..67218348 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java @@ -88,7 +88,7 @@ public class CellTagHandler extends AbstractXlsxTagHandler { break; } tempCellData.setType(CellDataTypeEnum.NUMBER); - tempCellData.setNumberValue(BigDecimal.valueOf(Double.parseDouble(tempDataString))); + tempCellData.setNumberValue(new BigDecimal(tempDataString)); break; default: throw new IllegalStateException("Cannot set values now"); diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java index 63141ba4..9841d2b2 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java @@ -1,32 +1,45 @@ package com.alibaba.easyexcel.test.temp; import java.io.File; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Map; import com.alibaba.easyexcel.test.demo.write.DemoData; import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.metadata.data.ReadCellData; +import com.alibaba.excel.util.NumberDataFormatterUtils; +import com.alibaba.excel.util.NumberUtils; import com.alibaba.excel.util.PositionUtils; import com.alibaba.excel.write.metadata.style.WriteCellStyle; import com.alibaba.excel.write.metadata.style.WriteFont; import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; import com.alibaba.fastjson.JSON; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.apache.poi.hssf.util.CellReference; +import org.apache.poi.ss.usermodel.DateUtil; import org.apache.poi.ss.usermodel.FillPatternType; import org.apache.poi.ss.usermodel.IndexedColors; +import org.junit.Assert; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.util.StringUtils; /** * 临时测试 * * @author Jiaju Zhuang **/ +@Slf4j public class Lock2Test { private static final Logger LOGGER = LoggerFactory.getLogger(Lock2Test.class); @@ -37,7 +50,10 @@ public class Lock2Test { // File file = TestFileUtil.readUserHomeFile("test/test6.xls"); File file = new File("/Users/zhuangjiaju/IdeaProjects/easyexcel/src/test/resources/converter/converter07.xlsx"); - List list = EasyExcel.read("/Users/zhuangjiaju/Downloads/测试格式.xlsx").sheet(0).headRowNumber(0).doReadSync(); + List list = EasyExcel.read("/Users/zhuangjiaju/Downloads/number1x.xls") + //.useDefaultListener(false) + .sheet(0) + .headRowNumber(0).doReadSync(); LOGGER.info("数据:{}", list.size()); for (Object data : list) { LOGGER.info("返回数据:{}", CollectionUtils.size(data)); @@ -109,17 +125,7 @@ public class Lock2Test { return list; } - private List data() { - List list = new ArrayList(); - for (int i = 0; i < 10; i++) { - DemoData data = new DemoData(); - data.setString("字符串" + i); - data.setDate(new Date()); - data.setDoubleData(0.56); - list.add(data); - } - return list; - } + @Test public void testc() throws Exception { @@ -151,10 +157,9 @@ public class Lock2Test { @Test public void test335() throws Exception { - - LOGGER.info("reslut:{}", PositionUtils.getCol("A10",null)); + LOGGER.info("reslut:{}", PositionUtils.getCol("A10", null)); LOGGER.info("reslut:{}", PositionUtils.getRow("A10")); - LOGGER.info("reslut:{}", PositionUtils.getCol("AB10",null)); + LOGGER.info("reslut:{}", PositionUtils.getCol("AB10", null)); LOGGER.info("reslut:{}", PositionUtils.getRow("AB10")); //LOGGER.info("reslut:{}", PositionUtils2.getCol("A10",null)); @@ -163,5 +168,191 @@ public class Lock2Test { //LOGGER.info("reslut:{}", PositionUtils2.getRow("AB10")); } + @Test + public void numberforamt() throws Exception { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + + //LOGGER.info("date:{}", + // NumberDataFormatterUtils.format(BigDecimal.valueOf(44727.99998842592), (short)200, "yyyy-MM-dd HH:mm:ss", + // null, + // null, null)); + // + //LOGGER.info("date:{}", + // NumberDataFormatterUtils.format(BigDecimal.valueOf(44728.99998842592), (short)200, "yyyy-MM-dd HH:mm:ss", + // null, + // null, null)); + // + //LOGGER.info("date:{}", + // NumberDataFormatterUtils.format(BigDecimal.valueOf(44729.99998836806), (short)200, "yyyy-MM-dd HH:mm:ss", + // null, + // null, null)); + // + //LOGGER.info("date:{}", + // NumberDataFormatterUtils.format(BigDecimal.valueOf(44727.99998842592).setScale(10, RoundingMode + // .HALF_UP), (short)200, "yyyy-MM-dd HH:mm:ss", + // null, + // null, null)); + // + //LOGGER.info("date:{}", + // NumberDataFormatterUtils.format(BigDecimal.valueOf(44728.99998842592).setScale(10, RoundingMode + // .HALF_UP), (short)200, "yyyy-MM-dd HH:mm:ss", + // null, + // null, null)); + + //44729.9999883681 + //44729.999988368058 + //LOGGER.info("date:{}", + // NumberDataFormatterUtils.format(BigDecimal.valueOf(44729.999988368058).setScale(10, RoundingMode + // .HALF_UP), (short)200, "yyyy-MM-dd HH:mm:ss", + // null, + // null, null)); + //LOGGER.info("date:{}",BigDecimal.valueOf(44729.999988368058).setScale(10, RoundingMode.HALF_UP).doubleValue + // ()); + + // 2022/6/17 23:59:59 + // 期望 44729.99998842592 + //LOGGER.info("data:{}", DateUtil.getJavaDate(44729.9999883681, true)); + LOGGER.info("data4:{}", DateUtil.getJavaDate(BigDecimal.valueOf(44729.999988368058) + .setScale(4, RoundingMode.HALF_UP).doubleValue(), false)); + LOGGER.info("data5:{}", DateUtil.getJavaDate(BigDecimal.valueOf(44729.999988368058) + .setScale(5, RoundingMode.HALF_UP).doubleValue(), false)); + LOGGER.info("data6:{}", DateUtil.getJavaDate(BigDecimal.valueOf(44729.999988368058) + .setScale(6, RoundingMode.HALF_UP).doubleValue(), false)); + LOGGER.info("data7:{}", DateUtil.getJavaDate(BigDecimal.valueOf(44729.999988368058) + .setScale(7, RoundingMode.HALF_UP).doubleValue(), false)); + LOGGER.info("data8:{}", DateUtil.getJavaDate(BigDecimal.valueOf(44729.999988368058) + .setScale(8, RoundingMode.HALF_UP).doubleValue(), false)); + + LOGGER.info("data:{}", format.format(DateUtil.getJavaDate(44729.999988368058, false))); + LOGGER.info("data:{}", format.format(DateUtil.getJavaDate(44729.9999883681, false))); + + LOGGER.info("data:{}", DateUtil.getJavaDate(Double.parseDouble("44729.999988368058"), false)); + LOGGER.info("data:{}", DateUtil.getJavaDate(Double.parseDouble("44729.9999883681"), false)); + + // 44729.999976851854 + // 44729.999988368058 + LOGGER.info("data:{}", DateUtil.getExcelDate(format.parse("2022-06-17 23:59:58"))); + // 44729.99998842592 + LOGGER.info("data:{}", DateUtil.getExcelDate(format.parse("2022-06-17 23:59:59"))); + + LOGGER.info("data:{}", DateUtil.getJavaDate(BigDecimal.valueOf(44729.999976851854) + .setScale(10, RoundingMode.HALF_UP).doubleValue(), false)); + LOGGER.info("data:{}", DateUtil.getJavaDate(BigDecimal.valueOf(44729.99998842592) + .setScale(10, RoundingMode.HALF_UP).doubleValue(), false)); + + LOGGER.info("data:{}", DateUtil.getJavaDate(BigDecimal.valueOf(44729.999976851854) + .setScale(5, RoundingMode.HALF_UP).doubleValue(), false)); + LOGGER.info("data:{}", DateUtil.getJavaDate(BigDecimal.valueOf(44729.99998842592) + .setScale(5, RoundingMode.HALF_UP).doubleValue(), false)); + } + + @Test + public void testDate() throws Exception { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + log.info("TT:{}", format.format(new Date(100L))); + log.info("TT:{}", new Date().getTime()); + } + + @Test + public void testDateAll() throws Exception { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + + long dateTime = 0L; + while (true) { + Date date = new Date(dateTime); + double excelDate = DateUtil.getExcelDate(date); + + Assert.assertEquals("测试基本转换错误" + dateTime, format.format(date), + format.format(DateUtil.getJavaDate(excelDate, false))); + Assert.assertEquals("测试精度5转换错误" + dateTime, format.format(date), + format.format(DateUtil.getJavaDate(BigDecimal.valueOf(excelDate) + .setScale(10, RoundingMode.HALF_UP).doubleValue(), false))); + LOGGER.info("date:{}", format2.format(DateUtil.getJavaDate(BigDecimal.valueOf(excelDate) + .setScale(10, RoundingMode.HALF_UP).doubleValue()))); + dateTime += 1000L; + // 30天输出 + if (dateTime % (24 * 60 * 60 * 1000) == 0) { + log.info("{}成功", format.format(date)); + } + if (dateTime > 1673957544750L) { + log.info("结束啦"); + break; + } + } + log.info("结束啦"); + + } + + @Test + public void numberforamt3() throws Exception { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + + List> list = EasyExcel.read("/Users/zhuangjiaju/Downloads/date3.xlsx") + .useDefaultListener(false) + .sheet(0) + .headRowNumber(0).doReadSync(); + LOGGER.info("数据:{}", list.size()); + for (Map readCellDataMap : list) { + ReadCellData data=readCellDataMap.get(0); + LOGGER.info("data:{}", format.format( + DateUtil.getJavaDate(data.getNumberValue().setScale(10, RoundingMode.HALF_UP).doubleValue(), false))); + + } + // + //LOGGER.info("data:{}", format.format(DateUtil.getJavaDate(44727.999988425923, false))); + //LOGGER.info("data:{}", format.format(DateUtil.getJavaDate(44729.999988368058, false))); + + } + + @Test + public void numberforamt4() throws Exception { + String fileName = TestFileUtil.getPath() + "simpleWrite" + System.currentTimeMillis() + ".xlsx"; + // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭 + // 如果这里想使用03 则 传入excelType参数即可 + EasyExcel.write(fileName, DemoData.class) + .sheet("模板") + .doWrite(() -> { + // 分页查询数据 + return data2(); + }); + + } + + private List data() { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + + List list = new ArrayList(); + for (int i = 0; i < 10; i++) { + DemoData data = new DemoData(); + data.setString("字符串" + i); + try { + data.setDate(format.parse("2032-01-18 09:00:01.995")); + } catch (ParseException e) { + throw new RuntimeException(e); + } + data.setDoubleData(0.56); + list.add(data); + } + return list; + } + + private List data2() { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + + List list = new ArrayList(); + for (int i = 0; i < 10; i++) { + DemoData data = new DemoData(); + data.setString("字符串" + i); + try { + data.setDate(format.parse("2032-01-18 09:00:00.")); + } catch (ParseException e) { + throw new RuntimeException(e); + } + data.setDoubleData(0.56); + list.add(data); + } + return list; + } } From b92c40554704ae3182847ad4a9938b052744c800 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 18 Jan 2023 23:23:14 +0800 Subject: [PATCH 65/68] =?UTF-8?q?*=20=E4=BF=AE=E5=A4=8D=E9=83=A8=E5=88=86x?= =?UTF-8?q?lsx=E8=AF=BB=E5=8F=96=E6=97=A5=E6=9C=9F=E5=8F=AF=E8=83=BD?= =?UTF-8?q?=E7=9B=B8=E5=B7=AE1=E7=A7=92=E7=9A=84bug=20[Issue=20#1956](http?= =?UTF-8?q?s://github.com/alibaba/easyexcel/issues/1956)=20*=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E9=83=A8=E5=88=86=E6=95=B0=E6=8D=AE=E7=B2=BE=E5=BA=A6?= =?UTF-8?q?=E5=92=8Cexcel=E4=B8=8D=E5=8C=B9=E9=85=8D=E7=9A=84bug=20[Issue?= =?UTF-8?q?=20#2805](https://github.com/alibaba/easyexcel/issues/2805)=20*?= =?UTF-8?q?=20=E4=B8=8D=E5=88=9B=E5=BB=BA=E5=AF=B9=E8=B1=A1=E7=9A=84?= =?UTF-8?q?=E8=AF=BB=E6=94=AF=E6=8C=81=E8=AF=BB=E5=8F=96=E9=9D=9E`String`?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E7=9A=84=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- .../v03/handlers/FormulaRecordHandler.java | 5 +- .../v03/handlers/NumberRecordHandler.java | 3 +- .../analysis/v07/handlers/CellTagHandler.java | 5 +- .../excel/constant/EasyExcelConstants.java | 19 ++++ .../converters/date/DateNumberConverter.java | 9 +- .../LocalDateNumberConverter.java | 5 +- .../string/StringNumberConverter.java | 5 +- .../excel/enums/ReadDefaultReturnEnum.java | 40 +++++++ .../alibaba/excel/metadata/data/CellData.java | 3 +- .../excel/metadata/data/ReadCellData.java | 37 +++++- .../excel/metadata/format/DataFormatter.java | 8 +- .../read/builder/ExcelReaderBuilder.java | 12 ++ .../listener/ModelBuildEventListener.java | 69 +++++++++-- .../excel/read/metadata/ReadWorkbook.java | 12 +- .../metadata/holder/ReadWorkbookHolder.java | 17 +++ .../alibaba/excel/util/ConverterUtils.java | 46 ++++++-- .../com/alibaba/excel/util/DateUtils.java | 71 ++++++++++++ .../core/compatibility/CompatibilityTest.java | 52 +++++++++ .../test/core/nomodel/NoModelDataTest.java | 52 ++++++++- .../easyexcel/test/demo/write/DemoData.java | 1 + .../easyexcel/test/temp/DemoData2.java | 35 ++++++ .../easyexcel/test/temp/DemoData3.java | 24 ++++ .../easyexcel/test/temp/Lock2Test.java | 107 ++++++++++++++++-- .../src/test/resources/compatibility/t05.xlsx | Bin 0 -> 3647 bytes .../src/test/resources/compatibility/t06.xlsx | Bin 0 -> 9332 bytes .../src/test/resources/compatibility/t07.xlsx | Bin 0 -> 19790 bytes pom.xml | 2 +- update.md | 6 + 29 files changed, 598 insertions(+), 49 deletions(-) create mode 100644 easyexcel-core/src/main/java/com/alibaba/excel/constant/EasyExcelConstants.java create mode 100644 easyexcel-core/src/main/java/com/alibaba/excel/enums/ReadDefaultReturnEnum.java create mode 100644 easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/DemoData2.java create mode 100644 easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/DemoData3.java create mode 100644 easyexcel-test/src/test/resources/compatibility/t05.xlsx create mode 100644 easyexcel-test/src/test/resources/compatibility/t06.xlsx create mode 100644 easyexcel-test/src/test/resources/compatibility/t07.xlsx diff --git a/README.md b/README.md index 960ec63e..7987c16c 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析 com.alibaba easyexcel - 3.1.5 + 3.2.0 ``` diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java index 09188cb2..dcf7f548 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java @@ -5,6 +5,7 @@ import java.util.Map; import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler; import com.alibaba.excel.constant.BuiltinFormats; +import com.alibaba.excel.constant.EasyExcelConstants; import com.alibaba.excel.context.xls.XlsReadContext; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.RowTypeEnum; @@ -56,7 +57,9 @@ public class FormulaRecordHandler extends AbstractXlsRecordHandler implements Ig break; case NUMERIC: tempCellData.setType(CellDataTypeEnum.NUMBER); - tempCellData.setNumberValue(BigDecimal.valueOf(frec.getValue())); + tempCellData.setOriginalNumberValue(BigDecimal.valueOf(frec.getValue())); + tempCellData.setNumberValue( + tempCellData.getOriginalNumberValue().round(EasyExcelConstants.EXCEL_MATH_CONTEXT)); int dataFormat = xlsReadContext.xlsReadWorkbookHolder().getFormatTrackingHSSFListener().getFormatIndex(frec); DataFormatData dataFormatData = new DataFormatData(); diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java index 1573b8e7..031b895f 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java @@ -4,6 +4,7 @@ import java.math.BigDecimal; import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler; import com.alibaba.excel.constant.BuiltinFormats; +import com.alibaba.excel.constant.EasyExcelConstants; import com.alibaba.excel.context.xls.XlsReadContext; import com.alibaba.excel.enums.RowTypeEnum; import com.alibaba.excel.metadata.data.DataFormatData; @@ -22,7 +23,7 @@ public class NumberRecordHandler extends AbstractXlsRecordHandler implements Ign @Override public void processRecord(XlsReadContext xlsReadContext, Record record) { NumberRecord nr = (NumberRecord)record; - ReadCellData cellData = ReadCellData.newInstance(BigDecimal.valueOf(nr.getValue()), nr.getRow(), + ReadCellData cellData = ReadCellData.newInstanceOriginal(BigDecimal.valueOf(nr.getValue()), nr.getRow(), (int)nr.getColumn()); short dataFormat = (short)xlsReadContext.xlsReadWorkbookHolder().getFormatTrackingHSSFListener().getFormatIndex( nr); diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java index 67218348..75e86aab 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java @@ -2,6 +2,7 @@ package com.alibaba.excel.analysis.v07.handlers; import java.math.BigDecimal; +import com.alibaba.excel.constant.EasyExcelConstants; import com.alibaba.excel.constant.ExcelXmlConstants; import com.alibaba.excel.context.xlsx.XlsxReadContext; import com.alibaba.excel.enums.CellDataTypeEnum; @@ -88,7 +89,9 @@ public class CellTagHandler extends AbstractXlsxTagHandler { break; } tempCellData.setType(CellDataTypeEnum.NUMBER); - tempCellData.setNumberValue(new BigDecimal(tempDataString)); + tempCellData.setOriginalNumberValue(new BigDecimal(tempDataString)); + tempCellData.setNumberValue( + tempCellData.getOriginalNumberValue().round(EasyExcelConstants.EXCEL_MATH_CONTEXT)); break; default: throw new IllegalStateException("Cannot set values now"); diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/constant/EasyExcelConstants.java b/easyexcel-core/src/main/java/com/alibaba/excel/constant/EasyExcelConstants.java new file mode 100644 index 00000000..cdc414fa --- /dev/null +++ b/easyexcel-core/src/main/java/com/alibaba/excel/constant/EasyExcelConstants.java @@ -0,0 +1,19 @@ +package com.alibaba.excel.constant; + +import java.math.MathContext; +import java.math.RoundingMode; + +/** + * Used to store constant + * + * @author Jiaju Zhuang + */ +public class EasyExcelConstants { + + /** + * Excel by default with 15 to store Numbers, and the double in Java can use to store number 17, led to the accuracy + * will be a problem. So you need to set up 15 to deal with precision + */ + public static final MathContext EXCEL_MATH_CONTEXT = new MathContext(15, RoundingMode.HALF_UP); + +} diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/converters/date/DateNumberConverter.java b/easyexcel-core/src/main/java/com/alibaba/excel/converters/date/DateNumberConverter.java index 34bb7536..02ba26aa 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/converters/date/DateNumberConverter.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/converters/date/DateNumberConverter.java @@ -9,6 +9,7 @@ import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.data.ReadCellData; import com.alibaba.excel.metadata.data.WriteCellData; import com.alibaba.excel.metadata.property.ExcelContentProperty; +import com.alibaba.excel.util.DateUtils; import org.apache.poi.ss.usermodel.DateUtil; @@ -33,11 +34,11 @@ public class DateNumberConverter implements Converter { public Date convertToJavaData(ReadCellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) { - return DateUtil.getJavaDate(cellData.getNumberValue().doubleValue(), - globalConfiguration.getUse1904windowing(), null); + return DateUtils.getJavaDate(cellData.getNumberValue().doubleValue(), + globalConfiguration.getUse1904windowing()); } else { - return DateUtil.getJavaDate(cellData.getNumberValue().doubleValue(), - contentProperty.getDateTimeFormatProperty().getUse1904windowing(), null); + return DateUtils.getJavaDate(cellData.getNumberValue().doubleValue(), + contentProperty.getDateTimeFormatProperty().getUse1904windowing()); } } diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/converters/localdatetime/LocalDateNumberConverter.java b/easyexcel-core/src/main/java/com/alibaba/excel/converters/localdatetime/LocalDateNumberConverter.java index f57f0bdc..4542fd08 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/converters/localdatetime/LocalDateNumberConverter.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/converters/localdatetime/LocalDateNumberConverter.java @@ -9,6 +9,7 @@ import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.data.ReadCellData; import com.alibaba.excel.metadata.data.WriteCellData; import com.alibaba.excel.metadata.property.ExcelContentProperty; +import com.alibaba.excel.util.DateUtils; import org.apache.poi.ss.usermodel.DateUtil; @@ -33,10 +34,10 @@ public class LocalDateNumberConverter implements Converter { public LocalDateTime convertToJavaData(ReadCellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) { - return DateUtil.getLocalDateTime(cellData.getNumberValue().doubleValue(), + return DateUtils.getLocalDateTime(cellData.getNumberValue().doubleValue(), globalConfiguration.getUse1904windowing()); } else { - return DateUtil.getLocalDateTime(cellData.getNumberValue().doubleValue(), + return DateUtils.getLocalDateTime(cellData.getNumberValue().doubleValue(), contentProperty.getDateTimeFormatProperty().getUse1904windowing()); } } diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/converters/string/StringNumberConverter.java b/easyexcel-core/src/main/java/com/alibaba/excel/converters/string/StringNumberConverter.java index 0d0813d0..ff96317d 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/converters/string/StringNumberConverter.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/converters/string/StringNumberConverter.java @@ -37,9 +37,8 @@ public class StringNumberConverter implements Converter { GlobalConfiguration globalConfiguration) { // If there are "DateTimeFormat", read as date if (contentProperty != null && contentProperty.getDateTimeFormatProperty() != null) { - return DateUtils.format( - DateUtil.getJavaDate(cellData.getNumberValue().doubleValue(), - contentProperty.getDateTimeFormatProperty().getUse1904windowing(), null), + return DateUtils.format(cellData.getNumberValue(), + contentProperty.getDateTimeFormatProperty().getUse1904windowing(), contentProperty.getDateTimeFormatProperty().getFormat()); } // If there are "NumberFormat", read as number diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/enums/ReadDefaultReturnEnum.java b/easyexcel-core/src/main/java/com/alibaba/excel/enums/ReadDefaultReturnEnum.java new file mode 100644 index 00000000..c0340d83 --- /dev/null +++ b/easyexcel-core/src/main/java/com/alibaba/excel/enums/ReadDefaultReturnEnum.java @@ -0,0 +1,40 @@ +package com.alibaba.excel.enums; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.Map; + +import com.alibaba.excel.metadata.data.CellData; +import com.alibaba.excel.util.StringUtils; + +/** + * Read not to {@code com.alibaba.excel.metadata.BasicParameter#clazz} value, the default will return type. + * + * @author Jiaju Zhuang + */ +public enum ReadDefaultReturnEnum { + /** + * default.The content of cells into string, is the same as you see in the excel. + */ + STRING, + + /** + * Returns the actual type. + * Will be automatically selected according to the cell contents what return type, will return the following class: + *
    + *
  1. {@link BigDecimal}
  2. + *
  3. {@link Boolean}
  4. + *
  5. {@link String}
  6. + *
  7. {@link LocalDateTime}
  8. + *
      + */ + ACTUAL_DATA, + + /** + * Return to {@link com.alibaba.excel.metadata.data.ReadCellData}, can decide which field you need. + */ + READ_CELL_DATA, + ; + +} diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/metadata/data/CellData.java b/easyexcel-core/src/main/java/com/alibaba/excel/metadata/data/CellData.java index 2f74ea9b..e70228f7 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/metadata/data/CellData.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/metadata/data/CellData.java @@ -1,6 +1,7 @@ package com.alibaba.excel.metadata.data; import java.math.BigDecimal; +import java.time.LocalDateTime; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.AbstractCell; @@ -57,6 +58,7 @@ public class CellData extends AbstractCell { } switch (type) { case STRING: + case DIRECT_STRING: case ERROR: if (StringUtils.isEmpty(stringValue)) { type = CellDataTypeEnum.EMPTY; @@ -76,5 +78,4 @@ public class CellData extends AbstractCell { } } - } diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/metadata/data/ReadCellData.java b/easyexcel-core/src/main/java/com/alibaba/excel/metadata/data/ReadCellData.java index e1bb57ca..9432e994 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/metadata/data/ReadCellData.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/metadata/data/ReadCellData.java @@ -1,7 +1,9 @@ package com.alibaba.excel.metadata.data; import java.math.BigDecimal; +import java.time.LocalDateTime; +import com.alibaba.excel.constant.EasyExcelConstants; import com.alibaba.excel.enums.CellDataTypeEnum; import lombok.EqualsAndHashCode; @@ -11,6 +13,7 @@ import lombok.Setter; /** * read cell data + *

      * * @author Jiaju Zhuang */ @@ -19,6 +22,29 @@ import lombok.Setter; @EqualsAndHashCode @NoArgsConstructor public class ReadCellData extends CellData { + + /** + * originalNumberValue vs numberValue + *

        + *
      1. + * NUMBER: + * originalNumberValue: Original data and the accuracy of his is 17, but in fact the excel only 15 precision to + * process the data + * numberValue: After correction of the data and the accuracy of his is 15 + * for example, originalNumberValue = `2087.0249999999996` , numberValue = `2087.03` + *
      2. + *
      3. + * DATE: + * originalNumberValue: Storage is a data type double, accurate to milliseconds + * dateValue: Based on double converted to a date format, he will revised date difference, accurate to seconds + * for example, originalNumberValue = `44729.99998836806` ,time is:`2022-06-17 23:59:58.995`, + * But in excel is displayed:` 2022-06-17 23:59:59`, dateValue = `2022-06-17 23:59:59` + *
      4. + *
          + * {@link CellDataTypeEnum#NUMBER} {@link CellDataTypeEnum#DATE} + */ + private BigDecimal originalNumberValue; + /** * data format. */ @@ -107,11 +133,21 @@ public class ReadCellData extends CellData { return cellData; } + public static ReadCellData newInstanceOriginal(BigDecimal numberValue, Integer rowIndex, Integer columnIndex) { + ReadCellData cellData = new ReadCellData<>(numberValue); + cellData.setRowIndex(rowIndex); + cellData.setColumnIndex(columnIndex); + cellData.setOriginalNumberValue(numberValue); + cellData.setNumberValue(numberValue.round(EasyExcelConstants.EXCEL_MATH_CONTEXT)); + return cellData; + } + @Override public ReadCellData clone() { ReadCellData readCellData = new ReadCellData<>(); readCellData.setType(getType()); readCellData.setNumberValue(getNumberValue()); + readCellData.setOriginalNumberValue(getOriginalNumberValue()); readCellData.setStringValue(getStringValue()); readCellData.setBooleanValue(getBooleanValue()); readCellData.setData(getData()); @@ -123,5 +159,4 @@ public class ReadCellData extends CellData { } return readCellData; } - } diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/metadata/format/DataFormatter.java b/easyexcel-core/src/main/java/com/alibaba/excel/metadata/format/DataFormatter.java index ba8fee47..1bd591e3 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/metadata/format/DataFormatter.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/metadata/format/DataFormatter.java @@ -212,10 +212,10 @@ public class DataFormatter { CellFormat cfmt = CellFormat.getInstance(locale, formatStr); // CellFormat requires callers to identify date vs not, so do so Object cellValueO = data; - if (DateUtil.isADateFormat(dataFormat, formatStr) && + if (DateUtils.isADateFormat(dataFormat, formatStr) && // don't try to handle Date value 0, let a 3 or 4-part format take care of it data.doubleValue() != 0.0) { - cellValueO = DateUtil.getJavaDate(data, use1904windowing); + cellValueO = DateUtils.getJavaDate(data, use1904windowing); } // Wrap and return (non-cachable - CellFormat does that) return new CellFormatResultWrapper(cfmt.apply(cellValueO)); @@ -243,6 +243,8 @@ public class DataFormatter { return format; } + + private Format createFormat(Short dataFormat, String dataFormatString) { String formatStr = dataFormatString; @@ -628,7 +630,7 @@ public class DataFormatter { // Hint about the raw excel value ((ExcelStyleDateFormatter)dateFormat).setDateToBeFormatted(data); } - return performDateFormatting(DateUtil.getJavaDate(data, use1904windowing), dateFormat); + return performDateFormatting(DateUtils.getJavaDate(data, use1904windowing), dateFormat); } /** diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/read/builder/ExcelReaderBuilder.java b/easyexcel-core/src/main/java/com/alibaba/excel/read/builder/ExcelReaderBuilder.java index d2a24b44..59fd7e1f 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/read/builder/ExcelReaderBuilder.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/read/builder/ExcelReaderBuilder.java @@ -13,6 +13,7 @@ import com.alibaba.excel.cache.ReadCache; import com.alibaba.excel.cache.selector.ReadCacheSelector; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.enums.CellExtraTypeEnum; +import com.alibaba.excel.enums.ReadDefaultReturnEnum; import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.event.SyncReadListener; import com.alibaba.excel.read.listener.ModelBuildEventListener; @@ -198,6 +199,17 @@ public class ExcelReaderBuilder extends AbstractExcelReaderParameterBuilder> cellDataMap, ReadSheetHolder readSheetHolder, + private Object buildNoModel(Map> cellDataMap, ReadSheetHolder readSheetHolder, AnalysisContext context) { int index = 0; - Map map = MapUtils.newLinkedHashMapWithExpectedSize(cellDataMap.size()); + Map map = MapUtils.newLinkedHashMapWithExpectedSize(cellDataMap.size()); for (Map.Entry> entry : cellDataMap.entrySet()) { Integer key = entry.getKey(); ReadCellData cellData = entry.getValue(); @@ -48,9 +57,23 @@ public class ModelBuildEventListener implements IgnoreExceptionReadListener convertedReadCellData = convertReadCellData(cellData, + context.readWorkbookHolder().getReadDefaultReturn(), readSheetHolder, context, key); + if (readDefaultReturn == ReadDefaultReturnEnum.READ_CELL_DATA) { + map.put(key, convertedReadCellData); + } else { + map.put(key, convertedReadCellData.getData()); + } + } } // fix https://github.com/alibaba/easyexcel/issues/2014 int headSize = calculateHeadSize(readSheetHolder); @@ -61,6 +84,38 @@ public class ModelBuildEventListener implements IgnoreExceptionReadListener cellData, ReadDefaultReturnEnum readDefaultReturn, + ReadSheetHolder readSheetHolder, AnalysisContext context, Integer columnIndex) { + Class classGeneric; + switch (cellData.getType()) { + case STRING: + case DIRECT_STRING: + case ERROR: + case EMPTY: + classGeneric = String.class; + break; + case BOOLEAN: + classGeneric = Boolean.class; + break; + case NUMBER: + DataFormatData dataFormatData = cellData.getDataFormatData(); + if (dataFormatData != null && DateUtils.isADateFormat(dataFormatData.getIndex(), + dataFormatData.getFormat())) { + classGeneric = LocalDateTime.class; + } else { + classGeneric = BigDecimal.class; + } + break; + default: + classGeneric = ConverterUtils.defaultClassGeneric; + break; + } + + return (ReadCellData)ConverterUtils.convertToJavaObject(cellData, null, ReadCellData.class, + classGeneric, null, readSheetHolder.converterMap(), context, context.readRowHolder().getRowIndex(), + columnIndex); + } + private int calculateHeadSize(ReadSheetHolder readSheetHolder) { if (readSheetHolder.excelReadHeadProperty().getHeadMap().size() > 0) { return readSheetHolder.excelReadHeadProperty().getHeadMap().size(); diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/ReadWorkbook.java b/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/ReadWorkbook.java index 4f3a3aab..a3713d7c 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/ReadWorkbook.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/ReadWorkbook.java @@ -11,6 +11,7 @@ import com.alibaba.excel.cache.ReadCache; import com.alibaba.excel.cache.selector.ReadCacheSelector; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.enums.CellExtraTypeEnum; +import com.alibaba.excel.enums.ReadDefaultReturnEnum; import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.read.listener.ModelBuildEventListener; import com.alibaba.excel.support.ExcelTypeEnum; @@ -62,7 +63,6 @@ public class ReadWorkbook extends ReadBasicParameter { /** * This object can be read in the Listener {@link AnalysisEventListener#invoke(Object, AnalysisContext)} * {@link AnalysisContext#getCustom()} - * */ private Object customObject; /** @@ -96,8 +96,18 @@ public class ReadWorkbook extends ReadBasicParameter { * Whether to use the default listener, which is used by default. *

          * The {@link ModelBuildEventListener} is loaded by default to convert the object. + * defualt is true. */ private Boolean useDefaultListener; + + /** + * Read not to {@code com.alibaba.excel.metadata.BasicParameter#clazz} value, the default will return type. + * Is only effective when set `useDefaultListener=true` or `useDefaultListener=null`. + * + * @see ReadDefaultReturnEnum + */ + private ReadDefaultReturnEnum readDefaultReturn; + /** * Read some additional fields. None are read by default. * diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/ReadWorkbookHolder.java b/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/ReadWorkbookHolder.java index a84cc315..63f8c1bf 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/ReadWorkbookHolder.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/ReadWorkbookHolder.java @@ -14,6 +14,7 @@ import com.alibaba.excel.cache.selector.SimpleReadCacheSelector; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.enums.CellExtraTypeEnum; import com.alibaba.excel.enums.HolderEnum; +import com.alibaba.excel.enums.ReadDefaultReturnEnum; import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.exception.ExcelAnalysisException; import com.alibaba.excel.read.metadata.ReadSheet; @@ -64,10 +65,20 @@ public class ReadWorkbookHolder extends AbstractReadHolder { * if false, Will transfer 'inputStream' to temporary files to improve efficiency */ private Boolean mandatoryUseInputStream; + /** * Default true */ private Boolean autoCloseStream; + + /** + * Read not to {@code com.alibaba.excel.metadata.BasicParameter#clazz} value, the default will return type. + * Is only effective when set `useDefaultListener=true` or `useDefaultListener=null`. + * + * @see ReadDefaultReturnEnum + */ + private ReadDefaultReturnEnum readDefaultReturn; + /** * Excel type */ @@ -146,6 +157,12 @@ public class ReadWorkbookHolder extends AbstractReadHolder { this.autoCloseStream = readWorkbook.getAutoCloseStream(); } + if (readWorkbook.getReadDefaultReturn() == null) { + this.readDefaultReturn = ReadDefaultReturnEnum.STRING; + } else { + this.readDefaultReturn = readWorkbook.getReadDefaultReturn(); + } + this.customObject = readWorkbook.getCustomObject(); if (readWorkbook.getIgnoreEmptyRow() == null) { this.ignoreEmptyRow = Boolean.TRUE; diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/util/ConverterUtils.java b/easyexcel-core/src/main/java/com/alibaba/excel/util/ConverterUtils.java index 02ea4a00..6359a99d 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/util/ConverterUtils.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/util/ConverterUtils.java @@ -84,24 +84,52 @@ public class ConverterUtils { public static Object convertToJavaObject(ReadCellData cellData, Field field, ExcelContentProperty contentProperty, Map> converterMap, AnalysisContext context, Integer rowIndex, Integer columnIndex) { - Class clazz; - if (field == null) { - clazz = String.class; - } else { - clazz = field.getType(); + return convertToJavaObject(cellData, field, null, null, contentProperty, converterMap, context, rowIndex, + columnIndex); + } + + /** + * Convert it into a Java object + * + * @param cellData + * @param field + * @param clazz + * @param contentProperty + * @param converterMap + * @param context + * @param rowIndex + * @param columnIndex + * @return + */ + public static Object convertToJavaObject(ReadCellData cellData, Field field, Class clazz, + Class classGeneric, ExcelContentProperty contentProperty, Map> converterMap, + AnalysisContext context, Integer rowIndex, Integer columnIndex) { + if (clazz == null) { + if (field == null) { + clazz = String.class; + } else { + clazz = field.getType(); + } } if (clazz == CellData.class || clazz == ReadCellData.class) { - Class classGeneric = getClassGeneric(field.getGenericType()); ReadCellData cellDataReturn = cellData.clone(); - cellDataReturn.setData(doConvertToJavaObject(cellData, classGeneric, contentProperty, converterMap, - context, rowIndex, columnIndex)); + cellDataReturn.setData( + doConvertToJavaObject(cellData, getClassGeneric(field, classGeneric), contentProperty, + converterMap, context, rowIndex, columnIndex)); return cellDataReturn; } return doConvertToJavaObject(cellData, clazz, contentProperty, converterMap, context, rowIndex, columnIndex); } - private static Class getClassGeneric(Type type) { + private static Class getClassGeneric(Field field, Class classGeneric) { + if (classGeneric != null) { + return classGeneric; + } + if (field == null) { + return defaultClassGeneric; + } + Type type = field.getGenericType(); if (!(type instanceof ParameterizedType)) { return defaultClassGeneric; } diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/util/DateUtils.java b/easyexcel-core/src/main/java/com/alibaba/excel/util/DateUtils.java index 22d7f3d9..fb19a105 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/util/DateUtils.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/util/DateUtils.java @@ -1,9 +1,11 @@ package com.alibaba.excel.util; +import java.math.BigDecimal; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.LocalDateTime; +import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Date; import java.util.HashMap; @@ -11,6 +13,8 @@ import java.util.Locale; import java.util.Map; import java.util.regex.Pattern; +import org.apache.poi.ss.usermodel.DateUtil; + /** * Date utils * @@ -184,6 +188,33 @@ public class DateUtils { } } + /** + * Format date + * + * @param date + * @param dateFormat + * @return + */ + public static String format(LocalDateTime date, String dateFormat) { + return format(date, dateFormat, null); + } + + /** + * Format date + * + * @param date + * @param dateFormat + * @return + */ + public static String format(BigDecimal date, Boolean use1904windowing, String dateFormat) { + if (date == null) { + return null; + } + LocalDateTime localDateTime = DateUtil.getLocalDateTime(date.doubleValue(), + BooleanUtils.isTrue(use1904windowing), true); + return format(localDateTime, dateFormat); + } + private static DateFormat getCacheDateFormat(String dateFormat) { Map dateFormatMap = DATE_FORMAT_THREAD_LOCAL.get(); if (dateFormatMap == null) { @@ -200,6 +231,46 @@ public class DateUtils { return simpleDateFormat; } + /** + * Given an Excel date with either 1900 or 1904 date windowing, + * converts it to a java.util.Date. + * + * Excel Dates and Times are stored without any timezone + * information. If you know (through other means) that your file + * uses a different TimeZone to the system default, you can use + * this version of the getJavaDate() method to handle it. + * + * @param date The Excel date. + * @param use1904windowing true if date uses 1904 windowing, + * or false if using 1900 date windowing. + * @return Java representation of the date, or null if date is not a valid Excel date + */ + public static Date getJavaDate(double date, boolean use1904windowing) { + //To calculate the Date, in the use of `org.apache.poi.ss.usermodel.DateUtil.getJavaDate(double, boolean, + // java.util.TimeZone, boolean), Date when similar `2023-01-01 00:00:00.500`, returns the`2023-01-01 + // 00:00:01`, but excel in fact shows the `2023-01-01 00:00:00`. + // `org.apache.poi.ss.usermodel.DateUtil.getLocalDateTime(double, boolean, boolean)` There is no problem. + return Date.from(getLocalDateTime(date, use1904windowing).atZone(ZoneId.systemDefault()).toInstant()); + } + + /** + * Given an Excel date with either 1900 or 1904 date windowing, + * converts it to a java.time.LocalDateTime. + * + * Excel Dates and Times are stored without any timezone + * information. If you know (through other means) that your file + * uses a different TimeZone to the system default, you can use + * this version of the getJavaDate() method to handle it. + * + * @param date The Excel date. + * @param use1904windowing true if date uses 1904 windowing, + * or false if using 1900 date windowing. + * @return Java representation of the date, or null if date is not a valid Excel date + */ + public static LocalDateTime getLocalDateTime(double date, boolean use1904windowing) { + return DateUtil.getLocalDateTime(date, use1904windowing, true); + } + /** * Determine if it is a date format. * diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/compatibility/CompatibilityTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/compatibility/CompatibilityTest.java index eadfd0a8..f4aae4a8 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/compatibility/CompatibilityTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/compatibility/CompatibilityTest.java @@ -1,10 +1,13 @@ package com.alibaba.easyexcel.test.core.compatibility; +import java.math.BigDecimal; import java.util.List; import java.util.Map; import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.constant.EasyExcelConstants; +import com.alibaba.excel.enums.ReadDefaultReturnEnum; import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; @@ -64,4 +67,53 @@ public class CompatibilityTest { Map row0 = list.get(0); Assert.assertEquals("QQSJK28F152A012242S0081", row0.get(5)); } + + @Test + public void t05() { + // https://github.com/alibaba/easyexcel/issues/1956 + // Excel read date needs to be rounded + List> list = EasyExcel + .read(TestFileUtil.getPath() + "compatibility/t05.xlsx") + .sheet() + .doReadSync(); + log.info("data:{}", JSON.toJSONString(list)); + Assert.assertEquals("2023-01-01 00:00:00", list.get(0).get(0)); + Assert.assertEquals("2023-01-01 00:00:00", list.get(1).get(0)); + Assert.assertEquals("2023-01-01 00:00:00", list.get(2).get(0)); + Assert.assertEquals("2023-01-01 00:00:01", list.get(3).get(0)); + Assert.assertEquals("2023-01-01 00:00:01", list.get(4).get(0)); + } + + @Test + public void t06() { + // Keep error precision digital format + List> list = EasyExcel + .read(TestFileUtil.getPath() + "compatibility/t06.xlsx") + .headRowNumber(0) + .sheet() + .doReadSync(); + log.info("data:{}", JSON.toJSONString(list)); + Assert.assertEquals("2087.03", list.get(0).get(2)); + } + + @Test + public void t07() { + // https://github.com/alibaba/easyexcel/issues/2805 + // Excel read date needs to be rounded + List> list = EasyExcel + .read(TestFileUtil.getPath() + "compatibility/t07.xlsx") + .readDefaultReturn(ReadDefaultReturnEnum.ACTUAL_DATA) + .sheet() + .doReadSync(); + log.info("data:{}", JSON.toJSONString(list)); + Assert.assertEquals(0, new BigDecimal("24.1998124").compareTo((BigDecimal)list.get(0).get(11))); + + list = EasyExcel + .read(TestFileUtil.getPath() + "compatibility/t07.xlsx") + .sheet() + .doReadSync(); + log.info("data:{}", JSON.toJSONString(list)); + Assert.assertEquals("24.20", list.get(0).get(11)); + } + } diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/nomodel/NoModelDataTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/nomodel/NoModelDataTest.java index 262ae35d..5abbcba7 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/nomodel/NoModelDataTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/nomodel/NoModelDataTest.java @@ -1,14 +1,20 @@ package com.alibaba.easyexcel.test.core.nomodel; import java.io.File; +import java.math.BigDecimal; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Map; import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.enums.ReadDefaultReturnEnum; +import com.alibaba.excel.metadata.data.ReadCellData; import com.alibaba.excel.util.DateUtils; +import com.alibaba.fastjson2.JSON; +import lombok.extern.slf4j.Slf4j; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.FixMethodOrder; @@ -19,6 +25,7 @@ import org.junit.runners.MethodSorters; * @author Jiaju Zhuang */ @FixMethodOrder(MethodSorters.NAME_ASCENDING) +@Slf4j public class NoModelDataTest { private static File file07; @@ -28,7 +35,6 @@ public class NoModelDataTest { private static File fileRepeat03; private static File fileRepeatCsv; - @BeforeClass public static void init() { file07 = TestFileUtil.createNewFile("noModel07.xlsx"); @@ -41,20 +47,20 @@ public class NoModelDataTest { @Test public void t01ReadAndWrite07() throws Exception { - readAndWrite(file07, fileRepeat07); + readAndWrite(file07, fileRepeat07, false); } @Test public void t02ReadAndWrite03() throws Exception { - readAndWrite(file03, fileRepeat03); + readAndWrite(file03, fileRepeat03, false); } @Test public void t03ReadAndWriteCsv() throws Exception { - readAndWrite(fileCsv, fileRepeatCsv); + readAndWrite(fileCsv, fileRepeatCsv, true); } - private void readAndWrite(File file, File fileRepeat) throws Exception { + private void readAndWrite(File file, File fileRepeat, boolean isCsv) throws Exception { EasyExcel.write(file).sheet().doWrite(data()); List> result = EasyExcel.read(file).headRowNumber(0).sheet().doReadSync(); Assert.assertEquals(10, result.size()); @@ -63,6 +69,42 @@ public class NoModelDataTest { Assert.assertEquals("109", data10.get(1)); Assert.assertEquals("2020-01-01 01:01:01", data10.get(2)); + List> actualDataList = EasyExcel.read(file) + .headRowNumber(0) + .readDefaultReturn(ReadDefaultReturnEnum.ACTUAL_DATA) + .sheet() + .doReadSync(); + log.info("actualDataList:{}", JSON.toJSONString(actualDataList)); + Assert.assertEquals(10, actualDataList.size()); + Map actualData10 = actualDataList.get(9); + Assert.assertEquals("string19", actualData10.get(0)); + if (isCsv) { + // CSV only string type + Assert.assertEquals("109", actualData10.get(1)); + Assert.assertEquals("2020-01-01 01:01:01", actualData10.get(2)); + } else { + Assert.assertEquals(0, new BigDecimal("109").compareTo((BigDecimal)actualData10.get(1))); + Assert.assertEquals(LocalDateTime.of(2020, 1, 1, 1, 1, 1), actualData10.get(2)); + } + + List>> readCellDataList = EasyExcel.read(file) + .headRowNumber(0) + .readDefaultReturn(ReadDefaultReturnEnum.READ_CELL_DATA) + .sheet() + .doReadSync(); + log.info("readCellDataList:{}", JSON.toJSONString(readCellDataList)); + Assert.assertEquals(10, readCellDataList.size()); + Map> readCellData10 = readCellDataList.get(9); + Assert.assertEquals("string19", readCellData10.get(0).getData()); + if (isCsv) { + // CSV only string type + Assert.assertEquals("109", readCellData10.get(1).getData()); + Assert.assertEquals("2020-01-01 01:01:01", readCellData10.get(2).getData()); + } else { + Assert.assertEquals(0, new BigDecimal("109").compareTo((BigDecimal)readCellData10.get(1).getData())); + Assert.assertEquals(LocalDateTime.of(2020, 1, 1, 1, 1, 1), readCellData10.get(2).getData()); + } + EasyExcel.write(fileRepeat).sheet().doWrite(result); result = EasyExcel.read(fileRepeat).headRowNumber(0).sheet().doReadSync(); Assert.assertEquals(10, result.size()); diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/DemoData.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/DemoData.java index 76b50584..fc3079a1 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/DemoData.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/DemoData.java @@ -24,6 +24,7 @@ public class DemoData { private Date date; @ExcelProperty("数字标题") private Double doubleData; + /** * 忽略这个字段 */ diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/DemoData2.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/DemoData2.java new file mode 100644 index 00000000..98693438 --- /dev/null +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/DemoData2.java @@ -0,0 +1,35 @@ +package com.alibaba.easyexcel.test.temp; + +import java.math.BigDecimal; +import java.util.Date; + +import com.alibaba.excel.annotation.ExcelIgnore; +import com.alibaba.excel.annotation.ExcelProperty; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +/** + * 基础数据类 + * + * @author Jiaju Zhuang + **/ +@Getter +@Setter +@EqualsAndHashCode +public class DemoData2 { + @ExcelProperty("字符串标题") + private String string; + @ExcelProperty("日期标题") + private Date date; + @ExcelProperty("数字标题") + private Double doubleData; + @ExcelProperty("数字标题2") + private BigDecimal bigDecimal; + /** + * 忽略这个字段 + */ + @ExcelIgnore + private String ignore; +} diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/DemoData3.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/DemoData3.java new file mode 100644 index 00000000..0be8ec7a --- /dev/null +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/DemoData3.java @@ -0,0 +1,24 @@ +package com.alibaba.easyexcel.test.temp; + +import java.time.LocalDateTime; +import java.util.Date; + +import com.alibaba.excel.annotation.ExcelIgnore; +import com.alibaba.excel.annotation.ExcelProperty; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +/** + * 基础数据类 + * + * @author Jiaju Zhuang + **/ +@Getter +@Setter +@EqualsAndHashCode +public class DemoData3 { + @ExcelProperty("日期时间标题") + private LocalDateTime localDateTime; +} diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java index 9841d2b2..8a782bbe 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java @@ -2,9 +2,13 @@ package com.alibaba.easyexcel.test.temp; import java.io.File; import java.math.BigDecimal; +import java.math.MathContext; import java.math.RoundingMode; +import java.text.DecimalFormat; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -50,7 +54,8 @@ public class Lock2Test { // File file = TestFileUtil.readUserHomeFile("test/test6.xls"); File file = new File("/Users/zhuangjiaju/IdeaProjects/easyexcel/src/test/resources/converter/converter07.xlsx"); - List list = EasyExcel.read("/Users/zhuangjiaju/Downloads/number1x.xls") + List list = EasyExcel.read( + "/Users/zhuangjiaju/IdeaProjects/easyexcel/easyexcel-test/target/test-classes/simpleWrite1674051907397.xlsx") //.useDefaultListener(false) .sheet(0) .headRowNumber(0).doReadSync(); @@ -125,8 +130,6 @@ public class Lock2Test { return list; } - - @Test public void testc() throws Exception { LOGGER.info("reslut:{}", JSON.toJSONString(new CellReference("B3"))); @@ -288,13 +291,13 @@ public class Lock2Test { public void numberforamt3() throws Exception { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); - List> list = EasyExcel.read("/Users/zhuangjiaju/Downloads/date3.xlsx") + List> list = EasyExcel.read("/Users/zhuangjiaju/Downloads/date3.xlsx") .useDefaultListener(false) .sheet(0) .headRowNumber(0).doReadSync(); LOGGER.info("数据:{}", list.size()); - for (Map readCellDataMap : list) { - ReadCellData data=readCellDataMap.get(0); + for (Map readCellDataMap : list) { + ReadCellData data = readCellDataMap.get(0); LOGGER.info("data:{}", format.format( DateUtil.getJavaDate(data.getNumberValue().setScale(10, RoundingMode.HALF_UP).doubleValue(), false))); @@ -317,10 +320,98 @@ public class Lock2Test { return data2(); }); + } + + @Test + public void numberforamt77() throws Exception { + String fileName = TestFileUtil.getPath() + "simpleWrite" + System.currentTimeMillis() + ".xlsx"; + // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭 + // 如果这里想使用03 则 传入excelType参数即可 + EasyExcel.write(fileName, DemoData3.class) + .sheet("模板") + .doWrite(() -> { + List list = new ArrayList<>(); + DemoData3 demoData3 = new DemoData3(); + demoData3.setLocalDateTime(LocalDateTime.of(2023, 1, 1, 0, 0, 0, 400000000)); + list.add(demoData3); + demoData3 = new DemoData3(); + demoData3.setLocalDateTime(LocalDateTime.of(2023, 1, 1, 0, 0, 0, 499000000)); + list.add(demoData3); + demoData3 = new DemoData3(); + demoData3.setLocalDateTime(LocalDateTime.of(2023, 1, 1, 0, 0, 0, 500000000)); + list.add(demoData3); + demoData3 = new DemoData3(); + demoData3.setLocalDateTime(LocalDateTime.of(2023, 1, 1, 0, 0, 0, 501000000)); + list.add(demoData3); + demoData3 = new DemoData3(); + demoData3.setLocalDateTime(LocalDateTime.of(2023, 1, 1, 0, 0, 0, 995000000)); + list.add(demoData3); + return list; + }); + + } + + @Test + public void numberforamt99() throws Exception { + LocalDateTime localDateTime=LocalDateTime.of(2023, 1, 1, 0, 0, 0, 995000000); + log.info("date:{}",localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"))); + + + } + @Test + public void numberforamt5() throws Exception { + String fileName = TestFileUtil.getPath() + "simpleWrite" + System.currentTimeMillis() + ".xlsx"; + // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭 + // 如果这里想使用03 则 传入excelType参数即可 + EasyExcel.write(fileName, DemoData.class) + .sheet("模板") + .doWrite(() -> { + // 分页查询数据 + return data3(); + }); + + } + + @Test + public void numberforamt6() throws Exception { + DecimalFormat decimalFormat = new DecimalFormat("#.#"); + BigDecimal bigDecimal = new BigDecimal(3101011021236149800L); + log.info("b:{}", bigDecimal); + log.info("b:{}", bigDecimal.setScale(-4, RoundingMode.HALF_UP)); + log.info("b:{}", decimalFormat.format(bigDecimal.setScale(-4, RoundingMode.HALF_UP))); + + } + + @Test + public void numberforamt7() throws Exception { + DecimalFormat decimalFormat = new DecimalFormat("#.#"); + BigDecimal bigDecimal = new BigDecimal(3.1010110212361498E+18).round(new MathContext(15, RoundingMode.HALF_UP)); + //bigDecimal. + + // bigDecimal + log.info("b:{}", bigDecimal); + log.info("b:{}", bigDecimal.setScale(-4, RoundingMode.HALF_UP)); + log.info("b:{}", decimalFormat.format(bigDecimal.setScale(-4, RoundingMode.HALF_UP))); + log.info("b:{}", decimalFormat.format(bigDecimal)); + + } + + private List data3() { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + + List list = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + DemoData2 data = new DemoData2(); + data.setString("字符串" + i); + data.setDoubleData(0.56); + data.setBigDecimal(BigDecimal.valueOf(3101011021236149800L)); + list.add(data); + } + return list; } - private List data() { + private List data() { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); List list = new ArrayList(); @@ -338,7 +429,7 @@ public class Lock2Test { return list; } - private List data2() { + private List data2() { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); List list = new ArrayList(); diff --git a/easyexcel-test/src/test/resources/compatibility/t05.xlsx b/easyexcel-test/src/test/resources/compatibility/t05.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..248ec7d1747ee016017363a7c9ca1a109f045d21 GIT binary patch literal 3647 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 literal 0 HcmV?d00001 diff --git a/easyexcel-test/src/test/resources/compatibility/t06.xlsx b/easyexcel-test/src/test/resources/compatibility/t06.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..b27be0279f226f78c59bb433c300574343e5830b GIT binary patch literal 9332 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 literal 0 HcmV?d00001 diff --git a/easyexcel-test/src/test/resources/compatibility/t07.xlsx b/easyexcel-test/src/test/resources/compatibility/t07.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..a7b0eac7486ad385679944783eb82f5acb1de624 GIT binary patch literal 19790 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 literal 0 HcmV?d00001 diff --git a/pom.xml b/pom.xml index de5d0681..70153a8e 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ - 3.1.5 + 3.2.0 UTF-8 1.8 true diff --git a/update.md b/update.md index 782e7a80..36c98000 100644 --- a/update.md +++ b/update.md @@ -1,3 +1,9 @@ +# 3.2.0 + +* 修复部分xlsx读取日期可能相差1秒的bug [Issue #1956](https://github.com/alibaba/easyexcel/issues/1956) +* 修复部分数据精度和excel不匹配的bug [Issue #2805](https://github.com/alibaba/easyexcel/issues/2805) +* 不创建对象的读支持读取原始的数据类型 + # 3.1.5 * 提高xlsx读取兼容性:兼用ns2开头的标签 From eadebfe67d505a845bad3438ae7040b3ffebc48a Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 18 Jan 2023 23:47:55 +0800 Subject: [PATCH 66/68] =?UTF-8?q?=E4=BF=AE=E6=94=B9javadoc=E6=8A=A5?= =?UTF-8?q?=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/alibaba/excel/EasyExcelFactory.java | 123 +++++------------- .../excel/enums/ReadDefaultReturnEnum.java | 10 +- .../excel/metadata/data/ReadCellData.java | 2 +- .../alibaba/excel/write/metadata/RowData.java | 8 +- 4 files changed, 46 insertions(+), 97 deletions(-) diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/EasyExcelFactory.java b/easyexcel-core/src/main/java/com/alibaba/excel/EasyExcelFactory.java index ef9b3ac3..80c40851 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/EasyExcelFactory.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/EasyExcelFactory.java @@ -14,25 +14,10 @@ import com.alibaba.excel.write.builder.ExcelWriterTableBuilder; /** * Reader and writer factory class * - *

          Quick start

          - *

          Read

          - *

          Sample1

          - * - *

          Sample2

          - * - *

          Write

          - * - *

          Sample1

          - * - *

          Sample2

          - * - * - * * @author jipengfei */ public class EasyExcelFactory { - /** * Build excel the write * @@ -45,8 +30,7 @@ public class EasyExcelFactory { /** * Build excel the write * - * @param file - * File to write + * @param file File to write * @return Excel writer builder */ public static ExcelWriterBuilder write(File file) { @@ -56,10 +40,8 @@ public class EasyExcelFactory { /** * Build excel the write * - * @param file - * File to write - * @param head - * Annotate the class for configuration information + * @param file File to write + * @param head Annotate the class for configuration information * @return Excel writer builder */ public static ExcelWriterBuilder write(File file, Class head) { @@ -74,8 +56,7 @@ public class EasyExcelFactory { /** * Build excel the write * - * @param pathName - * File path to write + * @param pathName File path to write * @return Excel writer builder */ public static ExcelWriterBuilder write(String pathName) { @@ -85,10 +66,8 @@ public class EasyExcelFactory { /** * Build excel the write * - * @param pathName - * File path to write - * @param head - * Annotate the class for configuration information + * @param pathName File path to write + * @param head Annotate the class for configuration information * @return Excel writer builder */ public static ExcelWriterBuilder write(String pathName, Class head) { @@ -103,8 +82,7 @@ public class EasyExcelFactory { /** * Build excel the write * - * @param outputStream - * Output stream to write + * @param outputStream Output stream to write * @return Excel writer builder */ public static ExcelWriterBuilder write(OutputStream outputStream) { @@ -114,10 +92,8 @@ public class EasyExcelFactory { /** * Build excel the write * - * @param outputStream - * Output stream to write - * @param head - * Annotate the class for configuration information. + * @param outputStream Output stream to write + * @param head Annotate the class for configuration information. * @return Excel writer builder */ public static ExcelWriterBuilder write(OutputStream outputStream, Class head) { @@ -141,8 +117,7 @@ public class EasyExcelFactory { /** * Build excel the writerSheet * - * @param sheetNo - * Index of sheet,0 base. + * @param sheetNo Index of sheet,0 base. * @return Excel sheet writer builder. */ public static ExcelWriterSheetBuilder writerSheet(Integer sheetNo) { @@ -152,8 +127,7 @@ public class EasyExcelFactory { /** * Build excel the 'writerSheet' * - * @param sheetName - * The name of sheet. + * @param sheetName The name of sheet. * @return Excel sheet writer builder. */ public static ExcelWriterSheetBuilder writerSheet(String sheetName) { @@ -163,10 +137,8 @@ public class EasyExcelFactory { /** * Build excel the 'writerSheet' * - * @param sheetNo - * Index of sheet,0 base. - * @param sheetName - * The name of sheet. + * @param sheetNo Index of sheet,0 base. + * @param sheetName The name of sheet. * @return Excel sheet writer builder. */ public static ExcelWriterSheetBuilder writerSheet(Integer sheetNo, String sheetName) { @@ -192,8 +164,7 @@ public class EasyExcelFactory { /** * Build excel the 'writerTable' * - * @param tableNo - * Index of table,0 base. + * @param tableNo Index of table,0 base. * @return Excel table writer builder. */ public static ExcelWriterTableBuilder writerTable(Integer tableNo) { @@ -216,8 +187,7 @@ public class EasyExcelFactory { /** * Build excel the read * - * @param file - * File to read. + * @param file File to read. * @return Excel reader builder. */ public static ExcelReaderBuilder read(File file) { @@ -227,10 +197,8 @@ public class EasyExcelFactory { /** * Build excel the read * - * @param file - * File to read. - * @param readListener - * Read listener. + * @param file File to read. + * @param readListener Read listener. * @return Excel reader builder. */ public static ExcelReaderBuilder read(File file, ReadListener readListener) { @@ -240,12 +208,9 @@ public class EasyExcelFactory { /** * Build excel the read * - * @param file - * File to read. - * @param head - * Annotate the class for configuration information. - * @param readListener - * Read listener. + * @param file File to read. + * @param head Annotate the class for configuration information. + * @param readListener Read listener. * @return Excel reader builder. */ public static ExcelReaderBuilder read(File file, Class head, ReadListener readListener) { @@ -263,8 +228,7 @@ public class EasyExcelFactory { /** * Build excel the read * - * @param pathName - * File path to read. + * @param pathName File path to read. * @return Excel reader builder. */ public static ExcelReaderBuilder read(String pathName) { @@ -274,10 +238,8 @@ public class EasyExcelFactory { /** * Build excel the read * - * @param pathName - * File path to read. - * @param readListener - * Read listener. + * @param pathName File path to read. + * @param readListener Read listener. * @return Excel reader builder. */ public static ExcelReaderBuilder read(String pathName, ReadListener readListener) { @@ -287,12 +249,9 @@ public class EasyExcelFactory { /** * Build excel the read * - * @param pathName - * File path to read. - * @param head - * Annotate the class for configuration information. - * @param readListener - * Read listener. + * @param pathName File path to read. + * @param head Annotate the class for configuration information. + * @param readListener Read listener. * @return Excel reader builder. */ public static ExcelReaderBuilder read(String pathName, Class head, ReadListener readListener) { @@ -310,8 +269,7 @@ public class EasyExcelFactory { /** * Build excel the read * - * @param inputStream - * Input stream to read. + * @param inputStream Input stream to read. * @return Excel reader builder. */ public static ExcelReaderBuilder read(InputStream inputStream) { @@ -321,10 +279,8 @@ public class EasyExcelFactory { /** * Build excel the read * - * @param inputStream - * Input stream to read. - * @param readListener - * Read listener. + * @param inputStream Input stream to read. + * @param readListener Read listener. * @return Excel reader builder. */ public static ExcelReaderBuilder read(InputStream inputStream, ReadListener readListener) { @@ -334,12 +290,9 @@ public class EasyExcelFactory { /** * Build excel the read * - * @param inputStream - * Input stream to read. - * @param head - * Annotate the class for configuration information. - * @param readListener - * Read listener. + * @param inputStream Input stream to read. + * @param head Annotate the class for configuration information. + * @param readListener Read listener. * @return Excel reader builder. */ public static ExcelReaderBuilder read(InputStream inputStream, Class head, ReadListener readListener) { @@ -366,8 +319,7 @@ public class EasyExcelFactory { /** * Build excel the 'readSheet' * - * @param sheetNo - * Index of sheet,0 base. + * @param sheetNo Index of sheet,0 base. * @return Excel sheet reader builder. */ public static ExcelReaderSheetBuilder readSheet(Integer sheetNo) { @@ -377,8 +329,7 @@ public class EasyExcelFactory { /** * Build excel the 'readSheet' * - * @param sheetName - * The name of sheet. + * @param sheetName The name of sheet. * @return Excel sheet reader builder. */ public static ExcelReaderSheetBuilder readSheet(String sheetName) { @@ -388,10 +339,8 @@ public class EasyExcelFactory { /** * Build excel the 'readSheet' * - * @param sheetNo - * Index of sheet,0 base. - * @param sheetName - * The name of sheet. + * @param sheetNo Index of sheet,0 base. + * @param sheetName The name of sheet. * @return Excel sheet reader builder. */ public static ExcelReaderSheetBuilder readSheet(Integer sheetNo, String sheetName) { diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/enums/ReadDefaultReturnEnum.java b/easyexcel-core/src/main/java/com/alibaba/excel/enums/ReadDefaultReturnEnum.java index c0340d83..4c2a317f 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/enums/ReadDefaultReturnEnum.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/enums/ReadDefaultReturnEnum.java @@ -23,11 +23,11 @@ public enum ReadDefaultReturnEnum { * Returns the actual type. * Will be automatically selected according to the cell contents what return type, will return the following class: *
            - *
          1. {@link BigDecimal}
          2. - *
          3. {@link Boolean}
          4. - *
          5. {@link String}
          6. - *
          7. {@link LocalDateTime}
          8. - *
              + *
            1. {@link BigDecimal}
            2. + *
            3. {@link Boolean}
            4. + *
            5. {@link String}
            6. + *
            7. {@link LocalDateTime}
            8. + *
            */ ACTUAL_DATA, diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/metadata/data/ReadCellData.java b/easyexcel-core/src/main/java/com/alibaba/excel/metadata/data/ReadCellData.java index 9432e994..1d3a2a2f 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/metadata/data/ReadCellData.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/metadata/data/ReadCellData.java @@ -40,7 +40,7 @@ public class ReadCellData extends CellData { * for example, originalNumberValue = `44729.99998836806` ,time is:`2022-06-17 23:59:58.995`, * But in excel is displayed:` 2022-06-17 23:59:59`, dateValue = `2022-06-17 23:59:59` *
          9. - *
              + *
            * {@link CellDataTypeEnum#NUMBER} {@link CellDataTypeEnum#DATE} */ private BigDecimal originalNumberValue; diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/write/metadata/RowData.java b/easyexcel-core/src/main/java/com/alibaba/excel/write/metadata/RowData.java index cb86a3e0..b1fe86a3 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/write/metadata/RowData.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/write/metadata/RowData.java @@ -18,17 +18,17 @@ public interface RowData { /** * Returns the number of elements in this collection. If this collection - * contains more than Integer.MAX_VALUE elements, returns - * Integer.MAX_VALUE. + * contains more than Integer.MAX_VALUE elements, returns + * Integer.MAX_VALUE. * * @return the number of elements in this collection */ int size(); /** - * Returns true if this collection contains no elements. + * Returns true if this collection contains no elements. * - * @return true if this collection contains no elements + * @return true if this collection contains no elements */ boolean isEmpty(); From 3e355843ad91f3b44e77a0655dfe903a85f1ea2f Mon Sep 17 00:00:00 2001 From: Frank Zhao Date: Fri, 3 Feb 2023 11:23:35 +0800 Subject: [PATCH 67/68] Update README.md Add contribution leaderboard badge --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7987c16c..9586e7b3 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ EasyExcel [![Build Status](https://github.com/alibaba/easyexcel/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/alibaba/easyexcel/actions/workflows/ci.yml?query=branch%3Amaster) [![Maven central](https://maven-badges.herokuapp.com/maven-central/com.alibaba/easyexcel/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.alibaba/easyexcel) [![License](http://img.shields.io/:license-apache-brightgreen.svg)](http://www.apache.org/licenses/LICENSE-2.0.html) +[![](https://img.shields.io/badge/EasyExcel-%E6%9F%A5%E7%9C%8B%E8%B4%A1%E7%8C%AE%E6%8E%92%E8%A1%8C%E6%A6%9C-orange)](https://opensource.alibaba.com/contribution_leaderboard/details?projectValue=easyexcel) # JAVA解析Excel工具 @@ -186,4 +187,4 @@ demo代码地址:[https://github.com/alibaba/easyexcel/blob/master/easyexcel-t EasyExcel.read(file.getInputStream(),UploadData.class,new UploadDataListener(uploadDAO)).sheet().doRead(); return"success"; } -``` \ No newline at end of file +``` From 0407921ed96947598f35016586e535e54aaa13c7 Mon Sep 17 00:00:00 2001 From: Frank Zhao Date: Fri, 3 Feb 2023 11:27:19 +0800 Subject: [PATCH 68/68] Update README_EN.md Add contribution leaderboard badge to README_EN --- README_EN.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README_EN.md b/README_EN.md index ae787bbb..619f4161 100644 --- a/README_EN.md +++ b/README_EN.md @@ -3,6 +3,7 @@ EasyExcel [![Build Status](https://github.com/alibaba/easyexcel/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/alibaba/easyexcel/actions/workflows/ci.yml?query=branch%3Amaster) [![Maven central](https://maven-badges.herokuapp.com/maven-central/com.alibaba/easyexcel/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.alibaba/easyexcel) [![License](http://img.shields.io/:license-apache-brightgreen.svg)](http://www.apache.org/licenses/LICENSE-2.0.html) +[![](https://img.shields.io/badge/EasyExcel-Check%20Your%20Contribution-orange)](https://opensource.alibaba.com/contribution_leaderboard/details?projectValue=easyexcel) [Communication Group 1 in QQ(Full): 662022184](https://jq.qq.com/?_wv=1027&k=1T21jJxh) [Communication Group 2 in QQ(Full): 1097936804](https://jq.qq.com/?_wv=1027&k=j5zEy6Xl)