diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/utils/poi/excel/handler/ExcelFillRowMergeStrategy.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/utils/poi/excel/handler/ExcelFillRowMergeStrategy.java index a196c2dd82..069898c31d 100644 --- a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/utils/poi/excel/handler/ExcelFillRowMergeStrategy.java +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/utils/poi/excel/handler/ExcelFillRowMergeStrategy.java @@ -9,8 +9,12 @@ import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMergeCell; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMergeCells; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet; -import java.util.List; +import java.lang.reflect.Field; /** * desc:按行对单元格合并策略 依据是第一列的值 @@ -21,26 +25,33 @@ import java.util.List; public class ExcelFillRowMergeStrategy implements RowWriteHandler { /** - * 需要合并的列 下标 + * 分段总数据量 本批次写入的数据总量 */ - private int[] mergeColumnIndexArr; + private Integer secTotalCount; + /** - * 从下标n行开始合并 + * 需要合并的列 下标 */ - private int mergeRowIndex; + private int[] mergeColumnIndexArr; + /** * 默认隐藏第一列 用于合并数据 */ private boolean hiddenFirst = true; + //已合并单元格数 + private int mergedTotalCount = 0; - public ExcelFillRowMergeStrategy(int mergeRowIndex, int[] mergeColumnIndexArr) { - this.mergeRowIndex = mergeRowIndex; + //合并行计数 + private int count; + + + + public ExcelFillRowMergeStrategy(int[] mergeColumnIndexArr) { this.mergeColumnIndexArr = mergeColumnIndexArr; } - public ExcelFillRowMergeStrategy(int mergeRowIndex, int[] mergeColumnIndexArr, boolean hiddenFirst) { - this.mergeRowIndex = mergeRowIndex; + public ExcelFillRowMergeStrategy(int[] mergeColumnIndexArr, boolean hiddenFirst) { this.mergeColumnIndexArr = mergeColumnIndexArr; this.hiddenFirst = hiddenFirst; } @@ -71,9 +82,24 @@ public class ExcelFillRowMergeStrategy implements RowWriteHandler { Cell preA1Cell = row.getSheet().getRow(curRowNum - 1).getCell(0); Object preA1Data = preA1Cell.getCellType() == CellType.STRING ? preA1Cell.getStringCellValue() : preA1Cell.getNumericCellValue(); - if (curA1Data.equals(preA1Data)) { - for (int value : mergeColumnIndexArr) { - mergeSameRow(writeSheetHolder, curRowNum, value); + log.info("curRowNum:{},是否相等:{}",curRowNum,curA1Data.equals(preA1Data)); + + if (curA1Data.equals(preA1Data)){ + count ++; + log.info("需要合并的列数:{}",count); + }else { + if (count > 0){ + log.info("需要合并了"); + for (int i = 0; i < mergeColumnIndexArr.length; i++) { + mergeSomeRow(writeSheetHolder,curRowNum,count,i); + } + count = 0; + } + } + + if (curRowNum == secTotalCount && count > 0){ + for (int i = 0; i < mergeColumnIndexArr.length; i++) { + mergeSomeRow(writeSheetHolder,curRowNum + 1,count,i); } } } @@ -81,7 +107,7 @@ public class ExcelFillRowMergeStrategy implements RowWriteHandler { } - private void mergeSameRow(WriteSheetHolder writeSheetHolder, int curRowIndex, int curColIndex) { + /*private void mergeSameRow(WriteSheetHolder writeSheetHolder, int curRowIndex, int curColIndex) { Sheet sheet = writeSheetHolder.getSheet(); List mergeRegions = sheet.getMergedRegions(); boolean isMerged = false; @@ -101,6 +127,36 @@ public class ExcelFillRowMergeStrategy implements RowWriteHandler { sheet.addMergedRegionUnsafe(cellRangeAddress); } } +*/ + + + /** + * 按列合并单元格 + * @param writeSheetHolder + * @param curRowIndex 当前行索引,有n行固定行就加n + * @param needMergeNum 需要合并的行数 + * @param curColIndex 需要合并的列 + */ + private void mergeSomeRow(WriteSheetHolder writeSheetHolder, int curRowIndex, int needMergeNum, int curColIndex) { + Sheet sheet = writeSheetHolder.getSheet(); + try { + CellRangeAddress cellAddresses = new CellRangeAddress(curRowIndex - needMergeNum - 1, curRowIndex-1, curColIndex, curColIndex); + Field sh = sheet.getClass().getDeclaredField("_sh"); + sh.setAccessible(true); + XSSFSheet shSheet = (XSSFSheet)sh.get(sheet); + CTWorksheet worksheet = shSheet.getCTWorksheet(); + CTMergeCells ctMergeCells = mergedTotalCount > 0 ? worksheet.getMergeCells() : worksheet.addNewMergeCells(); + CTMergeCell ctMergeCell = ctMergeCells.addNewMergeCell(); + ctMergeCell.setRef(cellAddresses.formatAsString()); + mergedTotalCount ++; + } catch (Exception e) { + e.printStackTrace(); + } + + } + public void setSecTotalCount(Integer secTotalCount) { + this.secTotalCount = secTotalCount; + } } diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/utils/poi/excel/handler/ExcelFillRowMergeStrategy2.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/utils/poi/excel/handler/ExcelFillRowMergeStrategy2.java new file mode 100644 index 0000000000..e1408b5b1b --- /dev/null +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/utils/poi/excel/handler/ExcelFillRowMergeStrategy2.java @@ -0,0 +1,105 @@ +package com.epmet.commons.tools.utils.poi.excel.handler; + +import com.alibaba.excel.write.handler.RowWriteHandler; +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; +import com.alibaba.excel.write.metadata.holder.WriteTableHolder; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.util.CellRangeAddress; + +import java.util.List; + +/** + * desc:按行对单元格合并策略 依据是第一列的值 + * + * @author liujianjun + */ +@Slf4j +public class ExcelFillRowMergeStrategy2 implements RowWriteHandler { + + /** + * 需要合并的列 下标 + */ + private int[] mergeColumnIndexArr; + /** + * 从下标n行开始合并 + */ + private int mergeRowIndex; + /** + * 默认隐藏第一列 用于合并数据 + */ + private boolean hiddenFirst = true; + + + public ExcelFillRowMergeStrategy2(int mergeRowIndex, int[] mergeColumnIndexArr) { + this.mergeRowIndex = mergeRowIndex; + this.mergeColumnIndexArr = mergeColumnIndexArr; + } + + public ExcelFillRowMergeStrategy2(int mergeRowIndex, int[] mergeColumnIndexArr, boolean hiddenFirst) { + this.mergeRowIndex = mergeRowIndex; + this.mergeColumnIndexArr = mergeColumnIndexArr; + this.hiddenFirst = hiddenFirst; + } + + @Override + public void beforeRowCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Integer rowIndex, Integer relativeRowIndex, Boolean isHead) { + + } + + @Override + public void afterRowCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer relativeRowIndex, Boolean isHead) { + // 隐藏id列 + if (hiddenFirst) { + writeSheetHolder.getSheet().setColumnHidden(0, true); + } + } + + + @Override + public void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer relativeRowIndex, Boolean isHead) { + //当前行索引 + int curRowNum = row.getRowNum(); + if (mergeColumnIndexArr != null && mergeColumnIndexArr.length > 0 && !isHead) { + //当前行第一列单元格 + Cell curA1Cell = row.getCell(0); + Object curA1Data = curA1Cell.getCellType() == CellType.STRING ? curA1Cell.getStringCellValue() : curA1Cell.getNumericCellValue(); + //上一行第一列单元格 + Cell preA1Cell = row.getSheet().getRow(curRowNum - 1).getCell(0); + Object preA1Data = preA1Cell.getCellType() == CellType.STRING ? preA1Cell.getStringCellValue() : preA1Cell.getNumericCellValue(); + + if (curA1Data.equals(preA1Data)) { + for (int value : mergeColumnIndexArr) { + mergeSameRow(writeSheetHolder, curRowNum, value); + } + } + } + + } + + + private void mergeSameRow(WriteSheetHolder writeSheetHolder, int curRowIndex, int curColIndex) { + Sheet sheet = writeSheetHolder.getSheet(); + List mergeRegions = sheet.getMergedRegions(); + boolean isMerged = false; + for (int i = 0; i < mergeRegions.size() && !isMerged; i++) { + CellRangeAddress cellRangeAddr = mergeRegions.get(i); + // 若上一个单元格已经被合并,则先移出原有的合并单元,再重新添加合并单元 + if (cellRangeAddr.isInRange(curRowIndex - 1, curColIndex)) { + sheet.removeMergedRegion(i); + cellRangeAddr.setLastRow(curRowIndex); + sheet.addMergedRegionUnsafe(cellRangeAddr); + isMerged = true; + } + } + // 若上一个单元格未被合并,则新增合并单元 + if (!isMerged) { + CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex, curColIndex); + sheet.addMergedRegionUnsafe(cellRangeAddress); + } + } + +} diff --git a/epmet-module/gov-org/gov-org-server/src/main/java/com/epmet/controller/HouseController.java b/epmet-module/gov-org/gov-org-server/src/main/java/com/epmet/controller/HouseController.java index 8bd6dd1b68..8e6ad94ea2 100644 --- a/epmet-module/gov-org/gov-org-server/src/main/java/com/epmet/controller/HouseController.java +++ b/epmet-module/gov-org/gov-org-server/src/main/java/com/epmet/controller/HouseController.java @@ -365,7 +365,7 @@ public class HouseController implements ResultDataResolver { FreezeAndFilter writeHandler = new FreezeAndFilter(); writeHandler.rowSplit = 2; //ExcelFillCellMergeStrategy mergeStrategy = new ExcelFillCellMergeStrategy(2,mergeRowArr,false); - ExcelFillRowMergeStrategy mergeStrategy2 = new ExcelFillRowMergeStrategy(2,mergeRowArr,false); + ExcelFillRowMergeStrategy mergeStrategy2 = new ExcelFillRowMergeStrategy(mergeRowArr,false); WriteSheet writeSheet = EasyExcel.writerSheet("Sheet1") .head(HouseMemberResultDTO.class) .registerWriteHandler(mergeStrategy2) @@ -379,6 +379,8 @@ public class HouseController implements ResultDataResolver { formDTO.setPageNo(formDTO.getPageNo() + NumConstant.ONE); long start = System.currentTimeMillis(); + //设置合并策略中的 本次数据的总条数 + mergeStrategy2.setSecTotalCount(dataList.getList().size()+1); excelWriter.write(dataList.getList(), writeSheet); log.info("getHouseUser doWrite cost:{}ms",System.currentTimeMillis() - start); if (CollectionUtils.isEmpty(dataList.getList())){