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