Java教程:若依框架自带导出功能如何实现相同值合并单元格功能

----这段时间一直在用若依的框架做开发,非常方便,其中自带了导入导出功能,但默认的导出只能是一条一条数据,没有合并行功能,于是就在若依的gitee提交仓库请求中找到了这个方案,使用简单,步骤如下。

第一步:我们在Excel中加入如下自定义注解

/**
 * 是否合并单元格.
 */
public boolean isMerge() default false;

第二步:在ExcelUtil 加入 mergeCells变量

/**
 * 要合并的单元格列
 */
public ArrayList<Integer> mergeCells = new ArrayList<>();

第三步:修改createExcelField方法如下

/**
 * 得到所有定义字段
 */
private void createExcelField()
{
    this.fields = new ArrayList<Object[]>();
    List<Field> tempFields = new ArrayList<>();
    tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields()));
    tempFields.addAll(Arrays.asList(clazz.getDeclaredFields()));
    for (Field field : tempFields)
    {
        // 单注解
        if (field.isAnnotationPresent(Excel.class))
        {
            putToField(field, field.getAnnotation(Excel.class));
        }

        // 多注解
        if (field.isAnnotationPresent(Excels.class))
        {
            Excels attrs = field.getAnnotation(Excels.class);
            Excel[] excels = attrs.value();
            for (Excel excel : excels)
            {
                putToField(field, excel);
            }
        }
    }
    //以下为新加值
    //筛选出需要合并的单元格的位置
    if(this.fields.size()>0){
        int column = 0;
        for (Object[] os : fields){
            Excel excel = (Excel) os[1];
                if(excel.isMerge()){
                    this.mergeCells.add(column);
                }
                column++;
            }
        }
    //以上为新加值
    this.fields = this.fields.stream().sorted(Comparator.comparing(objects -> ((Excel) objects[1]).sort())).collect(Collectors.toList());
    this.maxHeight = getRowHeight();
}

第四步:修改fillExcelData方法如下

/**
 * 填充excel数据
 * 
 * @param index 序号
 * @param row 单元格行
 */
public void fillExcelData(int index, Row row)
{
    int startNo = index * sheetSize;
    int endNo = Math.min(startNo + sheetSize, list.size());
    for (int i = startNo; i < endNo; i++)
    {
        row = sheet.createRow(i + 1 - startNo);
        // 得到导出对象.
        T vo = (T) list.get(i);
        int column = 0;
        for (Object[] os : fields)
        {
            Field field = (Field) os[0];
            Excel excel = (Excel) os[1];
            // 设置实体类私有属性可访问
            field.setAccessible(true);
            this.addCell(excel, row, vo, field, column++);
        }
    }
    //以下为新加值
    //合并单元格(需要传入要合并的列序号)
    if(mergeCells.size() > 0){
        for (int mergeCell : mergeCells) {
            mergeCells(sheet, mergeCell, 1, sheet.getLastRowNum());
        }
    }
}

第五步:合并方法

/**
 * @param sheet
 * @param cellLine  合并的列号
 * @param startRow  开始行
 * @param endRow  尾行
 **/
private void mergeCells(Sheet sheet, int cellLine,int startRow, int endRow) {
    // 获取第一行的数据,以便后面进行比较
    String s_will = getCellValue(sheet.getRow(startRow),cellLine).toString();
    //合并行数
    int count = 0;
    //数据比较,从第二行开始比较
    for (int i = 2; i <= endRow; i++) {
        //取出下一行的数据
        String s_current = getCellValue(sheet.getRow(i),cellLine).toString();
        //与相对的第一行的数据进行比较
        if (s_will.equals(s_current) && !s_will.equals("")) {
            //合并行数加一
            count++;
        } else {
            //如果合并行数大于等于1就合并,现将需要合并的行数进行合并
            if(count >= 1){
                //合并从开始行到合并的行数
                sheet.addMergedRegion(new CellRangeAddress( startRow, startRow+count,cellLine , cellLine));
            }
            //初始化数据,进行下一个单元格合并
            startRow = i;
            s_will = s_current;
            count = 0;
        }
        //最后个单元格合并
        if (i == endRow && count > 0) {
            sheet.addMergedRegion(new CellRangeAddress(startRow,startRow+count ,cellLine , cellLine));
        }
    }
}

具体实现,类属性加注解:

@Excel(name = "箱号", sort = 1, width = 25, isMerge = true)
private String caseNum;

最终效果:

在这里插入图片描述

感谢 @番茄你个马铃薯提交的分支记录, 

#好了,本次教程到这里就结束了,希望大家多多点赞关注支持(首席摸鱼师 微信同号),持续跟踪最新文章吧~

这段代码看起来是一个游戏或动画循环的一部分,使用了某种图形库(如EasyX)来处理双缓冲和屏幕刷新。以下是对这段代码的详细解释: ```cpp while (1) { BeginBatchDraw(); // 解决屏幕闪烁,一次性打印 updateBg(); // 更新背景 EndBatchDraw(); // 封装双缓存,一并显示 fly(); // 更新飞行物体的状态 Sleep(30); // 暂停30毫秒,检查错误 } ``` 1. **BeginBatchDraw()**:这个函数用于开始批量绘制,解决屏幕闪烁的问题。通过批量绘制,可以一次性将所有需要显示的内容绘制到缓冲区,然后再一次性显示到屏幕上。 2. **updateBg()**:这个函数用于更新背景。具体的实现可能包括清除屏幕、绘制新的背景内容等。 3. **EndBatchDraw()**:这个函数用于结束批量绘制,并将缓冲区的内容一次性显示到屏幕上。 4. **fly()**:这个函数用于更新飞行物体的状态。具体的实现可能包括更新位置、速度、方向等。 5. **Sleep(30)**:这个函数用于暂停程序执行30毫秒,以控制循环的执行速度。30毫秒的延迟大约对应于每秒33帧的刷新率。 ### 解释 - **双缓冲技术**:通过使用双缓冲技术,可以有效减少屏幕闪烁现象。双缓冲技术的基本思想是在内存中创建一个与屏幕显示区域一致的缓冲区,先将图形绘制到缓冲区中,然后再一次性将缓冲区的内容拷贝到屏幕上。 - **循环控制**:使用`while (1)`创建一个无限循环,使程序持续运行。`Sleep(30)`用于控制循环的执行速度,避免程序占用过多的CPU资源。 ### 注意事项 - **错误检查**:在实际应用中,建议在`Sleep(30)`之前添加错误检查,以确保`fly()`函数的执行不会导致程序崩溃。 - **性能优化**:根据实际需求,可以调整`Sleep(30)`中的时间参数,以达到最佳的刷新率和性能平衡。
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值