若依分离版本,使用注解合并单元格(升级)

若依分离版本导出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;
}
4.实现效果

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值