easypoi根据条件动态合并相同列(非表头)

1、找了很多文章都是合并表头,不太符合要求

要求:根据三列数据对另外两列数据合并,还有合计值


import org.apache.commons.collections.CollectionUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.jeecgframework.poi.excel.ExcelExportUtil;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.enmus.ExcelType;

import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

public class test {

public static void main(String[] args) {
    // 原始数据(使用类)
    List<Test> data = new ArrayList<>();
    data.add(new Test("17001525", "11000026", "1", "J4", new BigDecimal("0.00"), "haha"));
//    data.add(new Test("17001525", "11000026", "应交税费", "J4", new BigDecimal("0.00"), "haha1"));
//    data.add(new Test("17001526", "11000027", "应交税费", "", new BigDecimal("0.00"), "haha2"));
    data.add(new Test("17001526", "11000027", "应交税费", "J4", new BigDecimal("0.00"), "haha3"));
    data.add(new Test("17001526", "11000027", "应交税费", "J4", new BigDecimal("0.00"), "haha3"));
    data.add(new Test("合计", "", "", "", new BigDecimal("0.00"), ""));

    // 动态文件路径
    String filePath = "output55.xls";
    if (args.length > 0) {
        filePath = args[0];
    }
// 定义导出参数
//    ExportParams params=new ExportParams();
    ExportParams params = new ExportParams("列表数据", "导出人:"+"导出信息");
    params.setType(ExcelType.HSSF);
    // 导出Excel文件
    System.out.println("数量"+data.size());
    Workbook workbook = ExcelExportUtil.exportExcel(params, Test.class, new ArrayList<>());

    if (CollectionUtils.isEmpty(d)){
        System.out.println("00000");
    }
    // 获取第一个sheet页
    Sheet sheet = workbook.getSheetAt(0);


    // 合并单元格逻辑
    int startRow = 4; // 数据起始行(假设4行表头,有几行表头就写几行)
    // 创建工作簿和工作表
    try {
        String prevKey1 = null, prevKey2 = null, prevKey3 = null;
        // 遍历数据
        for (int i = 0; i < data.size(); i++) {
            InputInvoiceProfit input = data.get(i);
            String key1 = input.get1();
            String key2 = input.get2();
            String key3 = input.get3();
            // 创建行
            Row row = sheet.createRow(i+4);
            // 检查是否需要合并
            if (i == 0) {
                prevKey1 = key1;
                prevKey2 = key2;
                prevKey3 = key3;
                startRow = i+4;
            } else {
                if (key1.equals(prevKey1) && key2.equals(prevKey2) && key3.equals(prevKey3)) {
                    // 继续累积合并区域
                } else {
                    // 合并之前的区域
                    mergeCells(sheet, startRow, i+4-1, 20, 20);
                    mergeCells(sheet, startRow, i+4-1, 19, 19);
                    startRow = i+4;
                    prevKey1 = key1;
                    prevKey2 = key2;
                    prevKey3 = key3;
                }
            }

            // 填充单元格数据
            row.createCell(0).setCellValue(input.get1());
            row.createCell(1).setCellValue(input.get2());
            row.createCell(2).setCellValue(input.get3());
            row.createCell(3).setCellValue(input.get4());
            row.createCell(4).setCellValue(input.get5()); // 使用 toPlainString 避免精度丢失

          
        }

        // 处理最后一组合并
        if (data.size() > 0) {
            mergeCells(sheet, startRow, data.size()+4 - 1, 19, 19);
            mergeCells(sheet, startRow, data.size()+4 - 1, 20, 20);
        }
        // 写入文件
        try (FileOutputStream out = new FileOutputStream(filePath)) {
            workbook.write(out);
            System.out.println("Excel文件生成成功!路径:" + filePath);
        }
    } catch (IOException | NullPointerException | IllegalArgumentException e) {
        System.err.println("生成Excel文件时发生错误:" + e.getMessage());
        e.printStackTrace();
    }
}

    private static void mergeCells(Sheet sheet, int startRow, int endRow, int startCol, int endCol) {
        if (startRow < endRow) {
            CellRangeAddress region = new CellRangeAddress(startRow, endRow, startCol, endCol);
            sheet.addMergedRegion(region);
        }
    }
}

根据其中三列来进行合并,最后一行合计行的话按照真实数据导出的话,合并会有点问题,我特殊处理了一下,在最开始数据就过滤,把合计单独拿出来等最后合并再单独加入,也可以融到代码里直接处理,测试了几版总有点地方不对,为了下班就单独处理了~

这个思路就是遍历数据,然后符合条件的就先不进行处理,在最后遇到不符合条件的时候在进行合并处理,条件可以根据自己的需求写,Test换你自己的实体类

// 处理最后一组合并
            mergeCells(sheet, startRow, data.size()+4 - 1, 19, 19);
            mergeCells(sheet, startRow, data.size()+4 - 1, 20, 20);
//合计行的那个单独处理
            if (CollectionUtils.isNotEmpty(datao)){
                Test test= datao.get(0);
                Row row = sheet.createRow(data.size()+4);
                // 填充单元格数据
                同上可直接复制,也可
                // 处理最后一组合并
                mergeCells(sheet, data.size()+4, data.size()+4 , 19, 19);
                mergeCells(sheet, data.size()+4, data.size()+4 , 20, 20);
            }

注意:  Workbook workbook = ExcelExportUtil.exportExcel(params, Test.class, new ArrayList<>()); 如果把数据直接传到这个方法的话就会不走下边的导出合并

注:合并列起止根据自己需要改,字体,边框格式可以自己调一下。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值