diff --git a/epdc-commons-tools/pom.xml b/epdc-commons-tools/pom.xml index c917447..969db43 100644 --- a/epdc-commons-tools/pom.xml +++ b/epdc-commons-tools/pom.xml @@ -146,6 +146,25 @@ axis 1.4 + + com.alibaba + easyexcel + 3.1.1 + + + poi + org.apache.poi + + + poi-ooxml + org.apache.poi + + + poi-ooxml-schemas + org.apache.poi + + + diff --git a/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/ExcelUtils.java b/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/ExcelUtils.java index 7a8b175..d1290a3 100644 --- a/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/ExcelUtils.java +++ b/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/ExcelUtils.java @@ -355,4 +355,17 @@ public class ExcelUtils { } return hssfWorkbook; } + + public static ServletOutputStream getOutputStreamForExcel(String fileName, HttpServletResponse response) throws IOException { + fileName = URLEncoder.encode(fileName, "UTF-8"); + if (!fileName.endsWith(".xls") && !fileName.endsWith(".xlsx")){ + fileName = fileName + ".xlsx"; + } + response.setContentType("application/vnd.ms-excel"); + response.setCharacterEncoding("utf8"); + response.setHeader("Content-Disposition", "attachment;filename=" + fileName); + response.addHeader("Access-Control-Expose-Headers", "Content-disposition"); + + return response.getOutputStream(); + } } diff --git a/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/excel/EasyPoiExcelExportStylerImpl.java b/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/excel/EasyPoiExcelExportStylerImpl.java new file mode 100644 index 0000000..fd2a7ba --- /dev/null +++ b/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/excel/EasyPoiExcelExportStylerImpl.java @@ -0,0 +1,93 @@ +package com.elink.esua.epdc.commons.tools.utils.excel; + + +import cn.afterturn.easypoi.excel.export.styler.AbstractExcelExportStyler; +import cn.afterturn.easypoi.excel.export.styler.IExcelExportStyler; +import org.apache.poi.ss.usermodel.*; + + +/** + * desc:easypoi自定义表头颜色 + * + * @author: LiuJanJun + * @date: 2022/4/8 4:39 下午 + * @version: 1.0 + */ +public class EasyPoiExcelExportStylerImpl extends AbstractExcelExportStyler + implements IExcelExportStyler { + public EasyPoiExcelExportStylerImpl(Workbook workbook) { + super.createStyles(workbook); + } + + @Override + public CellStyle getTitleStyle(short color) { + CellStyle titleStyle = workbook.createCellStyle(); + Font font = this.workbook.createFont(); + // 字体加粗 + font.setBold(true); + font.setFontHeightInPoints((short) 12); + titleStyle.setFont(font); + //居中 + titleStyle.setAlignment(HorizontalAlignment.CENTER); + //垂直居中 + titleStyle.setVerticalAlignment(VerticalAlignment.CENTER); + //设置颜色 + titleStyle.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex()); + titleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); + titleStyle.setBorderRight(BorderStyle.THIN); + titleStyle.setBorderLeft(BorderStyle.THIN); + titleStyle.setBorderBottom(BorderStyle.THIN); + titleStyle.setBorderTop(BorderStyle.THIN); + titleStyle.setWrapText(true); + return titleStyle; + } + + @Override + public CellStyle getHeaderStyle(short color) { + CellStyle titleStyle = workbook.createCellStyle(); + Font font = workbook.createFont(); + font.setFontHeightInPoints((short) 12); + titleStyle.setFont(font); + titleStyle.setAlignment(HorizontalAlignment.CENTER); + titleStyle.setVerticalAlignment(VerticalAlignment.CENTER); + return titleStyle; + } + + /** + * desc:隔行样式 + * @param workbook + * @param isWarp + * @return + */ + @Override + public CellStyle stringNoneStyle(Workbook workbook, boolean isWarp) { + CellStyle style = workbook.createCellStyle(); + //style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setDataFormat(STRING_FORMAT); + if (isWarp) { + style.setWrapText(true); + } + + return style; + } + + /** + * desc:隔行样式 + * @param workbook + * @param isWarp + * @return + */ + @Override + public CellStyle stringSeptailStyle(Workbook workbook, boolean isWarp) { + CellStyle style = workbook.createCellStyle(); + //style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setDataFormat(STRING_FORMAT); + if (isWarp) { + style.setWrapText(true); + } + return style; + } + +} diff --git a/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/excel/ExportMultiView.java b/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/excel/ExportMultiView.java new file mode 100644 index 0000000..a00adc9 --- /dev/null +++ b/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/excel/ExportMultiView.java @@ -0,0 +1,32 @@ +package com.elink.esua.epdc.commons.tools.utils.excel; + +import cn.afterturn.easypoi.excel.entity.ExportParams; +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.util.List; + +/** + * desc:easypoi 导出多个sheet + * + * @author: LiuJanJun + * @date: 2022/3/29 1:13 下午 + * @version: 1.0 + */ +@Data +@AllArgsConstructor +public class ExportMultiView { + /** + * 导出的参数 比如设置表头 + */ + private ExportParams exportParams; + /** + * 要导出的数据列 + */ + private List dataList; + /** + * excel对应的类 + */ + private Class cls; + +} diff --git a/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/excel/converter/EasyExcelDateConverter.java b/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/excel/converter/EasyExcelDateConverter.java new file mode 100644 index 0000000..72f0a66 --- /dev/null +++ b/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/excel/converter/EasyExcelDateConverter.java @@ -0,0 +1,51 @@ +package com.elink.esua.epdc.commons.tools.utils.excel.converter; + +/** + * desc: + * + * @author: LiuJanJun + * @date: 2022/8/26 4:59 下午 + * @version: 1.0 + */ + +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.enums.CellDataTypeEnum; +import com.alibaba.excel.metadata.GlobalConfiguration; +import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.metadata.property.ExcelContentProperty; + +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * @Author: liujianjun + * @Date: 2022/7/19 + * @Description: yyyy-MM-dd easyExcel 日期转换 + */ +public class EasyExcelDateConverter implements Converter { + + private static final String PATTERN_YYYY_MM_DD = "yyyy-MM-dd"; + + @Override + public Class supportJavaTypeKey() { + return Converter.super.supportJavaTypeKey(); + } + + @Override + public CellDataTypeEnum supportExcelTypeKey() { + return Converter.super.supportExcelTypeKey(); + } + + @Override + public WriteCellData convertToExcelData(Date value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception { + SimpleDateFormat sdf = new SimpleDateFormat(PATTERN_YYYY_MM_DD); + String dateValue = sdf.format(value); + return new WriteCellData<>(dateValue); + } + + //@Override + //public Date convertToJavaData(ReadCellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception { + // SimpleDateFormat sdf = new SimpleDateFormat(PATTERN_YYYY_MM_DD); + // return sdf.parse(cellData.getStringValue()); + //} +} \ No newline at end of file diff --git a/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/excel/handler/ColumnWidthStyleStrategy.java b/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/excel/handler/ColumnWidthStyleStrategy.java new file mode 100644 index 0000000..fd9e84f --- /dev/null +++ b/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/excel/handler/ColumnWidthStyleStrategy.java @@ -0,0 +1,96 @@ +package com.elink.esua.epdc.commons.tools.utils.excel.handler; + +/** + * desc:设置columnWith宽度 + * + * @author: LiuJanJun + * @date: 2022/4/28 5:05 下午 + * @version: 1.0 + */ + +import com.alibaba.excel.enums.CellDataTypeEnum; +import com.alibaba.excel.metadata.Head; +import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.util.MapUtils; +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; +import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.poi.ss.usermodel.Cell; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +/** + * Take the width of the longest column as the width. + *

+ * This is not very useful at the moment, for example if you have Numbers it will cause a newline.And the length is not + * exactly the same as the actual length. + * + * @author Jiaju Zhuang + */ +public class ColumnWidthStyleStrategy extends AbstractColumnWidthStyleStrategy { + + private static final int MAX_COLUMN_WIDTH = 255; + /** + * 是否 根据内容设置宽度 + */ + private boolean isSetContentWidth = false; + + private final Map> cache = MapUtils.newHashMapWithExpectedSize(8); + + + + @Override + protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List> cellDataList, Cell cell, + Head head, + Integer relativeRowIndex, Boolean isHead) { + boolean needSetWidth = (isHead || isSetContentWidth) && CollectionUtils.isNotEmpty(cellDataList); + if (!needSetWidth) { + return; + } + Map maxColumnWidthMap = cache.computeIfAbsent(writeSheetHolder.getSheetNo(), k -> new HashMap<>(16)); + Integer columnWidth = dataLength(cellDataList, cell, isHead); + if (columnWidth < 0) { + return; + } + if (columnWidth > MAX_COLUMN_WIDTH) { + columnWidth = MAX_COLUMN_WIDTH; + } + Integer maxColumnWidth = maxColumnWidthMap.get(cell.getColumnIndex()); + if (maxColumnWidth == null || columnWidth > maxColumnWidth) { + maxColumnWidthMap.put(cell.getColumnIndex(), columnWidth); + writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), columnWidth * 256); + } + } + + private Integer dataLength(List> cellDataList, Cell cell, Boolean isHead) { + if (isHead) { + return cell.getStringCellValue().getBytes().length+3; + } + WriteCellData cellData = cellDataList.get(0); + CellDataTypeEnum type = cellData.getType(); + if (type == null) { + return -1; + } + switch (type) { + case STRING: + return cellData.getStringValue().getBytes().length; + case BOOLEAN: + return cellData.getBooleanValue().toString().getBytes().length; + case NUMBER: + return cellData.getNumberValue().toString().getBytes().length; + default: + return -1; + } + } + + public ColumnWidthStyleStrategy() { + + } + + public ColumnWidthStyleStrategy(boolean isSetContentWidth) { + this.isSetContentWidth = isSetContentWidth; + } +} diff --git a/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/excel/handler/ExcelFillCellMergeStrategy.java b/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/excel/handler/ExcelFillCellMergeStrategy.java new file mode 100644 index 0000000..6abfef0 --- /dev/null +++ b/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/excel/handler/ExcelFillCellMergeStrategy.java @@ -0,0 +1,132 @@ +package com.elink.esua.epdc.commons.tools.utils.excel.handler; + +import com.alibaba.excel.metadata.Head; +import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.write.handler.CellWriteHandler; +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; +import com.alibaba.excel.write.metadata.holder.WriteTableHolder; +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 + */ +public class ExcelFillCellMergeStrategy implements CellWriteHandler { + + /** + * 需要合并的列 下标 + */ + private int[] mergeColumnIndexArr; + /** + * 从下标n行开始合并 + */ + private int mergeRowIndex; + /** + * 默认隐藏第一列 用于合并数据 + */ + private boolean hiddenFirst = true; + + public ExcelFillCellMergeStrategy() { + } + + public ExcelFillCellMergeStrategy(int mergeRowIndex, int[] mergeColumnIndexArr) { + this.mergeRowIndex = mergeRowIndex; + this.mergeColumnIndexArr = mergeColumnIndexArr; + } + public ExcelFillCellMergeStrategy(int mergeRowIndex, int[] mergeColumnIndexArr,boolean hiddenFirst) { + this.mergeRowIndex = mergeRowIndex; + this.mergeColumnIndexArr = mergeColumnIndexArr; + this.hiddenFirst = hiddenFirst; + } + + @Override + public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) { + + } + + @Override + public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { + // 隐藏id列 + if (hiddenFirst ){ + writeSheetHolder.getSheet().setColumnHidden(0, true); + } + } + + @Override + public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List> list, Cell cell, Head head, Integer integer, Boolean aBoolean) { + int curRowIndex = cell.getRowIndex(); + int curColIndex = cell.getColumnIndex(); + if (curRowIndex <= mergeRowIndex) { + return; + } + //如果不指定 合并的列则全部列进行 合并判断 + if (mergeColumnIndexArr == null) { + mergeWithPrevRow(writeSheetHolder, cell, curRowIndex, curColIndex); + } else { + //合并指定的列号 + for (int columnIndex : mergeColumnIndexArr) { + if (curColIndex == columnIndex) { + mergeWithPrevRow(writeSheetHolder, cell, curRowIndex, curColIndex); + } + } + } + } + + /** + * 当前单元格向上合并 + * + * @param writeSheetHolder + * @param cell 当前单元格 + * @param curRowIndex 当前行 + * @param curColIndex 当前列 + */ + private void mergeWithPrevRow(WriteSheetHolder writeSheetHolder, Cell cell, int curRowIndex, int curColIndex) { + // 当前行的第一个Cell + Cell curFirstCell = cell.getSheet().getRow(curRowIndex).getCell(0); + Object curFirstData = curFirstCell.getCellType() == CellType.STRING ? curFirstCell.getStringCellValue() : curFirstCell.getNumericCellValue(); + // 上一行的第一个Cell + Cell preFirstCell = cell.getSheet().getRow(curRowIndex - 1).getCell(0); + Object preFirstData = preFirstCell.getCellType() == CellType.STRING ? preFirstCell.getStringCellValue() : preFirstCell.getNumericCellValue(); + + if (curFirstData.equals(preFirstData)) { + Object curData = cell.getCellType() == CellType.STRING ? cell.getStringCellValue() : cell.getNumericCellValue(); + Cell preCell = cell.getSheet().getRow(curRowIndex - 1).getCell(curColIndex); + Object preData = preCell.getCellType() == CellType.STRING ? preCell.getStringCellValue() : preCell.getNumericCellValue(); + // 将当前单元格数据与上一个单元格数据比较 + Boolean dataBool = preData.equals(curData); + //此处需要注意:因为我是按照序号确定是否需要合并的,所以获取每一行第一列数据和上一行第一列数据进行比较,如果相等合并 + + + if (!dataBool) { + return; + } + 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.addMergedRegion(cellRangeAddr); + isMerged = true; + } + } + // 若上一个单元格未被合并,则新增合并单元 + if (!isMerged) { + CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex, curColIndex); + sheet.addMergedRegion(cellRangeAddress); + } + + } + } + +} diff --git a/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/excel/handler/ExcelFillRowMergeStrategy.java b/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/excel/handler/ExcelFillRowMergeStrategy.java new file mode 100644 index 0000000..ccd439b --- /dev/null +++ b/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/excel/handler/ExcelFillRowMergeStrategy.java @@ -0,0 +1,162 @@ +package com.elink.esua.epdc.commons.tools.utils.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 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.lang.reflect.Field; + +/** + * desc:按行对单元格合并策略 依据是第一列的值 + * + * @author liujianjun + */ +@Slf4j +public class ExcelFillRowMergeStrategy implements RowWriteHandler { + + /** + * 分段总数据量 本批次写入的数据总量 + */ + private Integer secTotalCount; + + /** + * 需要合并的列 下标 + */ + private int[] mergeColumnIndexArr; + + /** + * 默认隐藏第一列 用于合并数据 + */ + private boolean hiddenFirst = true; + + //已合并单元格数 + private int mergedTotalCount = 0; + + //合并行计数 + private int count; + + + + public ExcelFillRowMergeStrategy(int[] mergeColumnIndexArr) { + this.mergeColumnIndexArr = mergeColumnIndexArr; + } + + public ExcelFillRowMergeStrategy(int[] mergeColumnIndexArr, boolean hiddenFirst) { + 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(); + + 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); + } + } + } + + } + + + /*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); + } + } +*/ + + + /** + * 按列合并单元格 + * @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/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/excel/handler/ExcelFillRowMergeStrategy2.java b/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/excel/handler/ExcelFillRowMergeStrategy2.java new file mode 100644 index 0000000..909c6cd --- /dev/null +++ b/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/excel/handler/ExcelFillRowMergeStrategy2.java @@ -0,0 +1,105 @@ +package com.elink.esua.epdc.commons.tools.utils.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/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/excel/handler/FreezeAndFilter.java b/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/excel/handler/FreezeAndFilter.java new file mode 100644 index 0000000..175395c --- /dev/null +++ b/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/utils/excel/handler/FreezeAndFilter.java @@ -0,0 +1,46 @@ +package com.elink.esua.epdc.commons.tools.utils.excel.handler; + +/** + * desc:easyExcel 冻结标题 + * + * @author: LiuJanJun + * @date: 2022/4/11 10:27 上午 + * @version: 1.0 + */ + +import com.alibaba.excel.write.handler.SheetWriteHandler; +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; +import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.util.CellRangeAddress; + + +public class FreezeAndFilter implements SheetWriteHandler { + + public int colSplit = 0, rowSplit = 1, leftmostColumn = 0, topRow = 1; + public String autoFilterRange = "1:1"; + private boolean isFilter; + + public FreezeAndFilter() { + + } + public FreezeAndFilter(boolean isFilter) { + this.isFilter = isFilter; + } + + @Override + public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) { + + } + + @Override + public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) { + Sheet sheet = writeSheetHolder.getSheet(); + sheet.createFreezePane(colSplit, rowSplit, leftmostColumn, topRow); + //不让他筛选 + if (isFilter){ + sheet.setAutoFilter(CellRangeAddress.valueOf(autoFilterRange)); + } + } +} +