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<>()); 如果把数据直接传到这个方法的话就会不走下边的导出合并
注:合并列起止根据自己需要改,字体,边框格式可以自己调一下。