POI动态合并单元格核心代码
关键字 CellRangeAddress
CellRangeAddress
类用于指定要合并的单元格区域。它的构造方法有四个参数,分别是起始行、结束行、起始列和结束列的索引。
以下是 CellRangeAddress
的构造方法和参数的说明:
public CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol)
firstRow
:要合并的单元格区域的起始行索引(从 0 开始计数)。lastRow
:要合并的单元格区域的结束行索引(从 0 开始计数)。firstCol
:要合并的单元格区域的起始列索引(从 0 开始计数)。lastCol
:要合并的单元格区域的结束列索引(从 0 开始计数)。
合并的单元格区域是一个矩形区域,由起始行和列索引与结束行和列索引确定。例如,可以使用 new CellRangeAddress(0, 1, 0, 2)
来指定要将第一行到第二行的前三列合并成一个单元格。
确保根据你的需求设置正确的起始行、结束行、起始列和结束列索引,以获得期望的合并效果。
// 模拟数据
List<Daochu> customerInfos = new ArrayList<>();
// 填充模拟数据...
customerInfos.add(new Daochu("1","单位名称1", "省级单位1", 10, 666.88));
customerInfos.add(new Daochu("2","单位名称2", "省级单位2", 1, 6266.88));
customerInfos.add(new Daochu("2","单位名称2", "省级单位2", 1, 6266.88));
customerInfos.add(new Daochu("2","单位名称2", "省级单位2", 1, 6266.88));
customerInfos.add(new Daochu("2","单位名称2", "省级单位2", 1, 6266.88));
customerInfos.add(new Daochu("3","合计", "-", 1, 6266.88));
// ...
int rowNum = 4; // 开始行号
String lastUnitName = null;
int lastUnitRow = 4; // 合并单元格的起始行
int unitCount = 1;
CellRangeAddress lastUnitRangeAddress = null;
CellRangeAddress lastNumberRangeAddress = null;
for (Daochu customerInfo : customerInfos) {
Row row5 = sheet.createRow(rowNum++);
// 序号
Cell cellFirst = row5.createCell(0);
cellFirst.setCellValue(unitCount);
boolean merged = false;
// 单位名称
if (lastUnitName != null && lastUnitName.equals(customerInfo.getUnitName())) {
if (lastUnitRangeAddress != null) {
//如果需要合并的单元格已经存在合并操作先删除 然后在合并
deleteMergedRegion(sheet, lastUnitRangeAddress);
}
// 如果与上一个单位名称不同,则合并上一个单位名称的单元格
lastUnitRangeAddress = new CellRangeAddress(lastUnitRow, rowNum - 1, 1, 1);
sheet.addMergedRegion(lastUnitRangeAddress);
//合并序号
if (lastNumberRangeAddress != null) {
deleteMergedRegion(sheet, lastNumberRangeAddress);
}
lastNumberRangeAddress = new CellRangeAddress(lastUnitRow, rowNum - 1, 0, 0);
sheet.addMergedRegion(lastNumberRangeAddress);
merged = true;
}
Cell unitNameCell = row5.createCell(1);
unitNameCell.setCellValue(customerInfo.getUnitName());
// 客户省级/直属单位
row5.createCell(2).setCellValue(customerInfo.getCustomerLevel());
// 本月新增
row5.createCell(3).setCellValue(customerInfo.getProjectNumberCurrentMonth());
// 本月收入
row5.createCell(4).setCellValue(customerInfo.getIncomeCurrentMonth());
// 其他数据...
for (Cell cell5 : row5) {
cell5.setCellStyle(cententStyle);
}
lastUnitName = customerInfo.getUnitName(); // 更新最后处理的单位名称
if (!merged) {
lastUnitRow = rowNum - 1;
unitCount ++;
lastNumberRangeAddress = lastUnitRangeAddress = null;
}
}
private static void deleteMergedRegion(Sheet sheet, CellRangeAddress cellRangeAddress) {
List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();
for (int i = 0; i < mergedRegions.size(); i++) {
CellRangeAddress rangeAddress = mergedRegions.get(i);
if (rangeAddress.equals(cellRangeAddress)) {
sheet.removeMergedRegion(i);
break;
}
}
}