10 changed files with 749 additions and 0 deletions
@ -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; |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -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; |
||||
|
|
||||
|
} |
||||
@ -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<Date> { |
||||
|
|
||||
|
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());
|
||||
|
//}
|
||||
|
} |
||||
@ -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. |
||||
|
* <p> |
||||
|
* 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<Integer, Map<Integer, Integer>> cache = MapUtils.newHashMapWithExpectedSize(8); |
||||
|
|
||||
|
|
||||
|
|
||||
|
@Override |
||||
|
protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> cellDataList, Cell cell, |
||||
|
Head head, |
||||
|
Integer relativeRowIndex, Boolean isHead) { |
||||
|
boolean needSetWidth = (isHead || isSetContentWidth) && CollectionUtils.isNotEmpty(cellDataList); |
||||
|
if (!needSetWidth) { |
||||
|
return; |
||||
|
} |
||||
|
Map<Integer, Integer> 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<WriteCellData<?>> 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; |
||||
|
} |
||||
|
} |
||||
@ -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<WriteCellData<?>> 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<CellRangeAddress> 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); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -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<CellRangeAddress> 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; |
||||
|
} |
||||
|
} |
||||
@ -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<CellRangeAddress> 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); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -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)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
Loading…
Reference in new issue