若依分离版本导出excel使用注解合并单元格-CSDN博客文章浏览阅读244次。在若依分离版本的 Excel 注解内增加 isMerge() 方法,在导出时获取有该属性的字段,获取该字段的列所在位置后,对该sheet进行遍历,判断当前行的值是否与下一行的值一致,不一致则进行记录,遍历完成,再对数据进行合并。https://blog.csdn.net/Yxh_255/article/details/136419957 上次用了isMerge()方法实现了数据重复合并的功能,但是因为数据的问题,合并的很乱,后来要求:根据一个列的重复情况,合并其他列
代码:
1.新增注解
/**
* 需要合并的Excel注解集
*
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MergeExcels {
/**
* 根据哪个字段去合并
* @return
*/
public String key() default "";
/**
* 需要合并的注解集合
* @return
*/
public Excel[] value();
}
2.在若依分离版本的ExcelUtil工具类内增加方法
/**
* 数据从第几行开始
*/
private int dataRowNum;
/**
* 跟随一个key,key 合并多长,其他字段都合并这个长度
*/
public void MergeExcelsCell(){
int lastRowNum = sheet.getLastRowNum();
//判断实体类上是否有这个注解,判断sheet内是否有值
if (!this.clazz.isAnnotationPresent(MergeExcels.class) || lastRowNum == 0) return;
//获取注解集合
MergeExcels attrs = this.clazz.getAnnotation(MergeExcels.class);
String key = attrs.key();
Excel[] excels = attrs.value();
if(excels.length == 0) return;
//获取key所在位置,并获取
Map<String, Integer> filedIndexMap = getFiledIndexMap();
Integer keyCellIndex = filedIndexMap.get(key);
//遍历数据,获取key相同的起止行
List<String> mergeIndexList = new ArrayList<>();
Integer fileEndIndex = dataRowNum;
lastRowNum += 1;
for (int i = this.dataRowNum; i < lastRowNum; i++) {
Integer nextIndex = i + 1;
if(nextIndex >= lastRowNum){
if(fileEndIndex != i) mergeIndexList.add(fileEndIndex + "-" + i);
continue;
}
String thisValue = sheet.getRow(i).getCell(keyCellIndex).getStringCellValue();
String nextValue = sheet.getRow(nextIndex).getCell(keyCellIndex).getStringCellValue();
if (!StringUtils.equals(thisValue, nextValue)) {
if(fileEndIndex != i){
mergeIndexList.add(fileEndIndex + "-" + i);
}
fileEndIndex = nextIndex;
}
}
if(CollectionUtil.isEmpty(mergeIndexList)) return;
//获取所有需要合并的列
Set<Integer> mergeCellIndexSet = new HashSet<>();
for (Excel excel : excels) {
if(!filedIndexMap.containsKey(excel.name())) continue;
mergeCellIndexSet.add(filedIndexMap.get(excel.name()));
}
//开始合并
for (String range : mergeIndexList) {
String[] split = range.split("-");
for (Integer cellIndex : mergeCellIndexSet) {
sheet.addMergedRegion(new CellRangeAddress(Integer.parseInt(split[0]), Integer.parseInt(split[1]),
cellIndex, cellIndex));
}
}
}
/**
* 获取每个字段所在的位置
* @return
*/
public Map<String,Integer> getFiledIndexMap(){
// 定义一个map用于存放列的位置与数据索引位置
Map<String, Integer> mergeFieldIndexMap = new HashMap<>();
Row titleRow = this.sheet.getRow(dataRowNum - 1);
for (int i = 0; i < titleRow.getPhysicalNumberOfCells(); i++) {
Cell cell = titleRow.getCell(i);
if (StringUtils.isNull(cell)) continue;
String headerName = String.valueOf(this.getCellValue(titleRow, i));
mergeFieldIndexMap.put(headerName, i);
}
return mergeFieldIndexMap;
}
/**------------3.调用该方法,在工具类内的writeSheet()该方法内进行改动----------*/
/**
* 创建写入数据到Sheet
*/
public void writeSheet() {
// 取出一共有多少个sheet.
int sheetNo = Math.max(1, (int) Math.ceil(list.size() * 1.0 / sheetSize));
for (int index = 0; index < sheetNo; index++) {
createSheet(sheetNo, index);
// 产生一行
Row row = sheet.createRow(rownum);
dataRowNum = rownum + 1;
//创建需要合并的集合
int column = 0;
// 写入各个字段的列头名称
for (Object[] os : fields) {
Excel excel = (Excel) os[1];
this.createCell(excel, row, column++);
if (excel.isMerge()) mergeFields.add(os);
}
if (Type.EXPORT.equals(type)) {
fillExcelData(index, row);
addStatisticsRow();
mergedCell();
MergeExcelsCell();
}
}
}
3.在实体类上引用
@Data
@MergeExcels(key = "企业注册号", value = {
@Excel(name = "顺序号"),
@Excel(name = "企业注册号"),
@Excel(name = "企业名称"),
@Excel(name = "统一社会信用代码"),
@Excel(name = "户内档案卷数"),
@Excel(name = "快递单号"),
@Excel(name = "备注"),
@Excel(name = "备迁入机关注")
}
)
public class xxxxx implements Serializable {
@Excel(name = "顺序号")
private Long serialNumber;
@Excel(name = "企业注册号")
private String enterpriseRegistrationNumber;
@Excel(name = "企业名称")
private String enterpriseName;
@Excel(name = "统一社会信用代码")
private String unifySocialCreditCode;
@Excel(name = "备注")
private String remark;
@Excel(name = "快递单号")
private String expressNo;
@Excel(name = "件号")
private String barNo;
@Excel(name = "档号")
private String filingNo;
@Excel(name = "类型")
private String applicationType;
}