From fc59b8601fdda770f2328f35cc9ebd68ac7bab67 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Tue, 9 Nov 2021 20:01:54 +0800 Subject: [PATCH] =?UTF-8?q?*=20`fill`=E7=9A=84=E6=83=85=E5=86=B5=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=20`afterRowDispose`=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../write/style/ContentLoopMerge.java | 2 +- .../executor/ExcelWriteFillExecutor.java | 28 ++++-- .../excel/write/handler/RowWriteHandler.java | 6 +- .../excel/write/merge/LoopMergeStrategy.java | 21 ++-- .../fill/annotation/FillAnnotationData.java | 36 +++++++ .../annotation/FillAnnotationDataTest.java | 92 ++++++++++++++++++ .../test/temp/large/TempLargeDataTest.java | 47 ++++++++- src/test/resources/fill/annotation.xls | Bin 0 -> 26624 bytes src/test/resources/fill/annotation.xlsx | Bin 0 -> 10692 bytes update.md | 1 + 10 files changed, 210 insertions(+), 23 deletions(-) create mode 100644 src/test/java/com/alibaba/easyexcel/test/core/fill/annotation/FillAnnotationData.java create mode 100644 src/test/java/com/alibaba/easyexcel/test/core/fill/annotation/FillAnnotationDataTest.java create mode 100644 src/test/resources/fill/annotation.xls create mode 100644 src/test/resources/fill/annotation.xlsx diff --git a/src/main/java/com/alibaba/excel/annotation/write/style/ContentLoopMerge.java b/src/main/java/com/alibaba/excel/annotation/write/style/ContentLoopMerge.java index af7bcecf..60654fe5 100644 --- a/src/main/java/com/alibaba/excel/annotation/write/style/ContentLoopMerge.java +++ b/src/main/java/com/alibaba/excel/annotation/write/style/ContentLoopMerge.java @@ -20,7 +20,7 @@ public @interface ContentLoopMerge { * * @return */ - int eachRow() default -1; + int eachRow() default 1; /** * Extend column diff --git a/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java b/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java index af90d8d5..6779e875 100644 --- a/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java +++ b/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java @@ -200,6 +200,9 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { } Set dataKeySet = new HashSet<>(dataMap.keySet()); + RowWriteHandlerContext rowWriteHandlerContext = WriteHandlerUtils.createRowWriteHandlerContext(writeContext, + null, relativeRowIndex, Boolean.FALSE); + for (AnalysisCell analysisCell : analysisCellList) { CellWriteHandlerContext cellWriteHandlerContext = WriteHandlerUtils.createCellWriteHandlerContext( writeContext, null, analysisCell.getRowIndex(), null, analysisCell.getColumnIndex(), @@ -215,7 +218,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadClazz(), variable); cellWriteHandlerContext.setExcelContentProperty(excelContentProperty); - createCell(analysisCell, fillConfig, cellWriteHandlerContext); + createCell(analysisCell, fillConfig, cellWriteHandlerContext, rowWriteHandlerContext); cellWriteHandlerContext.setOriginalValue(value); cellWriteHandlerContext.setOriginalFieldClass(FieldUtils.getFieldClass(dataMap, variable, value)); @@ -236,7 +239,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { cellWriteHandlerContext.setExcelContentProperty(ExcelContentProperty.EMPTY); cellWriteHandlerContext.setIgnoreFillStyle(Boolean.TRUE); - createCell(analysisCell, fillConfig, cellWriteHandlerContext); + createCell(analysisCell, fillConfig, cellWriteHandlerContext, rowWriteHandlerContext); Cell cell = cellWriteHandlerContext.getCell(); for (String variable : analysisCell.getVariableList()) { @@ -288,6 +291,11 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { } WriteHandlerUtils.afterCellDispose(cellWriteHandlerContext); } + + // In the case of the fill line may be called many times + if (rowWriteHandlerContext.getRow() != null) { + WriteHandlerUtils.afterRowDispose(rowWriteHandlerContext); + } } private Integer getRelativeRowIndex() { @@ -302,13 +310,16 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { } private void createCell(AnalysisCell analysisCell, FillConfig fillConfig, - CellWriteHandlerContext cellWriteHandlerContext) { + CellWriteHandlerContext cellWriteHandlerContext, RowWriteHandlerContext rowWriteHandlerContext) { Sheet cachedSheet = writeContext.writeSheetHolder().getCachedSheet(); if (WriteTemplateAnalysisCellTypeEnum.COMMON.equals(analysisCell.getCellType())) { Row row = cachedSheet.getRow(analysisCell.getRowIndex()); cellWriteHandlerContext.setRow(row); Cell cell = row.getCell(analysisCell.getColumnIndex()); cellWriteHandlerContext.setCell(cell); + rowWriteHandlerContext.setRow(row); + rowWriteHandlerContext.setRowIndex(analysisCell.getRowIndex()); + return; } Sheet sheet = writeContext.writeSheetHolder().getSheet(); @@ -345,7 +356,8 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { throw new ExcelGenerateException("The wrong direction."); } - Row row = createRowIfNecessary(sheet, cachedSheet, lastRowIndex, fillConfig, analysisCell, isOriginalCell); + Row row = createRowIfNecessary(sheet, cachedSheet, lastRowIndex, fillConfig, analysisCell, isOriginalCell, + rowWriteHandlerContext); cellWriteHandlerContext.setRow(row); cellWriteHandlerContext.setRowIndex(lastRowIndex); @@ -375,16 +387,17 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { } private Row createRowIfNecessary(Sheet sheet, Sheet cachedSheet, Integer lastRowIndex, FillConfig fillConfig, - AnalysisCell analysisCell, boolean isOriginalCell) { + AnalysisCell analysisCell, boolean isOriginalCell, RowWriteHandlerContext rowWriteHandlerContext) { + rowWriteHandlerContext.setRowIndex(lastRowIndex); Row row = sheet.getRow(lastRowIndex); if (row != null) { checkRowHeight(analysisCell, fillConfig, isOriginalCell, row); + rowWriteHandlerContext.setRow(row); return row; } row = cachedSheet.getRow(lastRowIndex); if (row == null) { - RowWriteHandlerContext rowWriteHandlerContext = WriteHandlerUtils.createRowWriteHandlerContext(writeContext, - lastRowIndex, null, Boolean.FALSE); + rowWriteHandlerContext.setRowIndex(lastRowIndex); WriteHandlerUtils.beforeRowCreate(rowWriteHandlerContext); if (fillConfig.getForceNewRow()) { @@ -405,6 +418,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { WriteHandlerUtils.afterRowCreate(rowWriteHandlerContext); } else { checkRowHeight(analysisCell, fillConfig, isOriginalCell, row); + rowWriteHandlerContext.setRow(row); } return row; } diff --git a/src/main/java/com/alibaba/excel/write/handler/RowWriteHandler.java b/src/main/java/com/alibaba/excel/write/handler/RowWriteHandler.java index afef0c97..c3dc708b 100644 --- a/src/main/java/com/alibaba/excel/write/handler/RowWriteHandler.java +++ b/src/main/java/com/alibaba/excel/write/handler/RowWriteHandler.java @@ -58,7 +58,8 @@ public interface RowWriteHandler extends WriteHandler { Integer relativeRowIndex, Boolean isHead) {} /** - * Called after all operations on the row have been completed.This method is not called when fill the data. + * Called after all operations on the row have been completed. + * In the case of the fill , may be called many times. * * @param context */ @@ -68,7 +69,8 @@ public interface RowWriteHandler extends WriteHandler { } /** - * Called after all operations on the row have been completed.This method is not called when fill the data. + * Called after all operations on the row have been completed. + * In the case of the fill , may be called many times. * * @param writeSheetHolder * @param writeTableHolder Nullable.It is null without using table writes. diff --git a/src/main/java/com/alibaba/excel/write/merge/LoopMergeStrategy.java b/src/main/java/com/alibaba/excel/write/merge/LoopMergeStrategy.java index 13ebe3cb..961db51f 100644 --- a/src/main/java/com/alibaba/excel/write/merge/LoopMergeStrategy.java +++ b/src/main/java/com/alibaba/excel/write/merge/LoopMergeStrategy.java @@ -1,13 +1,10 @@ package com.alibaba.excel.write.merge; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.util.CellRangeAddress; - import com.alibaba.excel.metadata.property.LoopMergeProperty; -import com.alibaba.excel.write.handler.AbstractRowWriteHandler; import com.alibaba.excel.write.handler.RowWriteHandler; -import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; -import com.alibaba.excel.write.metadata.holder.WriteTableHolder; +import com.alibaba.excel.write.handler.context.RowWriteHandlerContext; + +import org.apache.poi.ss.util.CellRangeAddress; /** * The regions of the loop merge @@ -55,15 +52,15 @@ public class LoopMergeStrategy implements RowWriteHandler { } @Override - public void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, - Integer relativeRowIndex, Boolean isHead) { - if (isHead) { + public void afterRowDispose(RowWriteHandlerContext context) { + if (context.getHead() || context.getRelativeRowIndex() == null) { return; } - if (relativeRowIndex % eachRow == 0) { - CellRangeAddress cellRangeAddress = new CellRangeAddress(row.getRowNum(), row.getRowNum() + eachRow - 1, + if (context.getRelativeRowIndex() % eachRow == 0) { + CellRangeAddress cellRangeAddress = new CellRangeAddress(context.getRowIndex(), + context.getRowIndex() + eachRow - 1, columnIndex, columnIndex + columnExtend - 1); - writeSheetHolder.getSheet().addMergedRegionUnsafe(cellRangeAddress); + context.getWriteSheetHolder().getSheet().addMergedRegionUnsafe(cellRangeAddress); } } diff --git a/src/test/java/com/alibaba/easyexcel/test/core/fill/annotation/FillAnnotationData.java b/src/test/java/com/alibaba/easyexcel/test/core/fill/annotation/FillAnnotationData.java new file mode 100644 index 00000000..bc4c2483 --- /dev/null +++ b/src/test/java/com/alibaba/easyexcel/test/core/fill/annotation/FillAnnotationData.java @@ -0,0 +1,36 @@ +package com.alibaba.easyexcel.test.core.fill.annotation; + +import java.util.Date; + +import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.annotation.format.DateTimeFormat; +import com.alibaba.excel.annotation.format.NumberFormat; +import com.alibaba.excel.annotation.write.style.ContentLoopMerge; +import com.alibaba.excel.annotation.write.style.ContentRowHeight; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +/** + * @author Jiaju Zhuang + */ +@Getter +@Setter +@EqualsAndHashCode +@ContentRowHeight(100) +public class FillAnnotationData { + @ExcelProperty("日期") + @DateTimeFormat("yyyy年MM月dd日HH时mm分ss秒") + private Date date; + + @ExcelProperty(value = "数字") + @NumberFormat("#.##%") + private Double number; + + @ContentLoopMerge(columnExtend = 2) + @ExcelProperty("字符串1") + private String string1; + @ExcelProperty("字符串2") + private String string2; +} diff --git a/src/test/java/com/alibaba/easyexcel/test/core/fill/annotation/FillAnnotationDataTest.java b/src/test/java/com/alibaba/easyexcel/test/core/fill/annotation/FillAnnotationDataTest.java new file mode 100644 index 00000000..93680d69 --- /dev/null +++ b/src/test/java/com/alibaba/easyexcel/test/core/fill/annotation/FillAnnotationDataTest.java @@ -0,0 +1,92 @@ +package com.alibaba.easyexcel.test.core.fill.annotation; + +import java.io.File; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import com.alibaba.easyexcel.test.util.TestFileUtil; +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.util.DateUtils; + +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.ss.usermodel.WorkbookFactory; +import org.apache.poi.ss.util.CellRangeAddress; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +/** + * @author Jiaju Zhuang + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class FillAnnotationDataTest { + + private static File file07; + private static File file03; + private static File fileTemplate07; + private static File fileTemplate03; + + @BeforeClass + public static void init() { + file07 = TestFileUtil.createNewFile("fillAnnotation07.xlsx"); + file03 = TestFileUtil.createNewFile("fillAnnotation03.xls"); + fileTemplate07 = TestFileUtil.readFile("fill" + File.separator + "annotation.xlsx"); + fileTemplate03 = TestFileUtil.readFile("fill" + File.separator + "annotation.xls"); + } + + @Test + public void t01ReadAndWrite07() throws Exception { + readAndWrite(file07, fileTemplate07); + } + + @Test + public void t02ReadAndWrite03() throws Exception { + readAndWrite(file03, fileTemplate03); + } + + private void readAndWrite(File file, File fileTemplate) throws Exception { + EasyExcel.write().file(file).head(FillAnnotationData.class).withTemplate(fileTemplate).sheet().doFill(data()); + + Workbook workbook = WorkbookFactory.create(file); + Sheet sheet = workbook.getSheetAt(0); + + Row row1 = sheet.getRow(1); + Assert.assertEquals(2000, row1.getHeight(), 0); + Cell cell10 = row1.getCell(0); + Date date = cell10.getDateCellValue(); + Assert.assertEquals(DateUtils.parseDate("2020-01-01 01:01:01").getTime(), date.getTime()); + String dataFormatString = cell10.getCellStyle().getDataFormatString(); + Assert.assertEquals("yyyy年MM月dd日HH时mm分ss秒", dataFormatString); + Cell cell11 = row1.getCell(1); + Assert.assertEquals(99.99, cell11.getNumericCellValue(), 2); + boolean hasMerge = false; + for (CellRangeAddress mergedRegion : sheet.getMergedRegions()) { + if (mergedRegion.getFirstRow() == 1 && mergedRegion.getLastRow() == 1 + && mergedRegion.getFirstColumn() == 2 && mergedRegion.getLastColumn() == 3) { + hasMerge = true; + } + } + Assert.assertTrue(hasMerge); + } + + private List data() throws Exception { + List list = new ArrayList<>(); + FillAnnotationData data = new FillAnnotationData(); + data.setDate(DateUtils.parseDate("2020-01-01 01:01:01")); + data.setNumber(99.99); + data.setString1("string1"); + data.setString2("string2"); + list.add(data); + list.add(data); + list.add(data); + list.add(data); + list.add(data); + return list; + } +} diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/large/TempLargeDataTest.java b/src/test/java/com/alibaba/easyexcel/test/temp/large/TempLargeDataTest.java index 1d97027b..934b62f5 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/large/TempLargeDataTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/large/TempLargeDataTest.java @@ -133,7 +133,7 @@ public class TempLargeDataTest { ExcelWriter excelWriter = EasyExcel.write(fileWriteTemp07, com.alibaba.easyexcel.test.core.large.LargeData.class).build(); WriteSheet writeSheet = EasyExcel.writerSheet().build(); - for (int j = 0; j < 2; j++) { + for (int j = 0; j < 5000; j++) { excelWriter.write(data(), writeSheet); } excelWriter.finish(); @@ -141,6 +141,51 @@ public class TempLargeDataTest { }); } + @Test + public void t04WriteExcelNo() throws Exception { + IntStream.rangeClosed(0, 10000).forEach(index -> { + ExcelWriter excelWriter = EasyExcel.write(fileWriteTemp07, + com.alibaba.easyexcel.test.core.large.LargeData.class).build(); + WriteSheet writeSheet = EasyExcel.writerSheet().build(); + for (int j = 0; j < 50; j++) { + excelWriter.write(data(), writeSheet); + } + excelWriter.finish(); + LOGGER.info("{} 完成", index); + }); + } + + @Test + public void t04WriteExcelPoi() throws Exception { + IntStream.rangeClosed(0, 10000).forEach(index -> { + try (FileOutputStream fileOutputStream = new FileOutputStream(fileWritePoi07)) { + SXSSFWorkbook workbook = new SXSSFWorkbook(500); + //workbook.setCompressTempFiles(true); + SXSSFSheet sheet = workbook.createSheet("sheet1"); + for (int i = 0; i < 100 * 50; i++) { + SXSSFRow row = sheet.createRow(i); + for (int j = 0; j < 25; j++) { + String str = "str-" + j + "-" + i; + //if (i + 10000 == j) { + SXSSFCell cell = row.createCell(j); + cell.setCellValue(str); + //System.out.println(str); + //} + } + if (i % 5000 == 0) { + LOGGER.info("{} write success.", i); + } + } + workbook.write(fileOutputStream); + workbook.dispose(); + workbook.close(); + } catch (Exception e) { + e.printStackTrace(); + } + LOGGER.info("{} 完成", index); + }); + } + private List data() { List list = new ArrayList<>(); diff --git a/src/test/resources/fill/annotation.xls b/src/test/resources/fill/annotation.xls new file mode 100644 index 0000000000000000000000000000000000000000..8fd19c5a7fa7300facc2a11f4f84c04ff6606b40 GIT binary patch literal 26624 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 QCy&p6qyF~DxRL*V0f)vO3;+NC literal 0 HcmV?d00001 diff --git a/src/test/resources/fill/annotation.xlsx b/src/test/resources/fill/annotation.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..5395232b481e77439aabf34c9a7904807862a721 GIT binary patch literal 10692 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 literal 0 HcmV?d00001 diff --git a/update.md b/update.md index 7e791d8d..8a695624 100644 --- a/update.md +++ b/update.md @@ -1,5 +1,6 @@ # 3.0.4 * 调整读写默认大小,防止大批量写的时候可能会full gc +* `fill`的情况新增 `afterRowDispose`事件 # 3.0.3 * 修复`HeadStyle`无效的bug