Apache POI插入行时条件格式未随行移位的问题求助
Apache POI插入行后条件格式未同步迁移的解决方案
我之前踩过一模一样的坑!当你用shiftRows移动行时,Apache POI默认只会更新单元格的引用,但条件格式的规则范围并不会自动跟着调整——这就是为什么原第10行移到第11行后,条件格式还绑定在新的第10行,原行的格式直接消失了。
你的copyRow方法里只处理了单元格的updateCellReferencesForShifting,完全没触及工作表的条件格式规则。这些规则存在于工作表的ConditionalFormatting集合中,每个规则都有自己的CellRangeAddress范围,移位后必须手动调整这些范围才能让格式跟着行走。
解决方案:手动调整条件格式的行范围
在执行shiftRows之后、创建新行之前,添加一段代码遍历所有条件格式规则,调整它们的行号范围。具体步骤如下:
- 获取工作表中所有的条件格式对象
- 遍历每个条件格式的所有单元格范围
- 如果范围的起始行 >= 你要移位的起始行(也就是代码里的
nFirstRow),就把范围的起始行和结束行都加上移位的数量(nNumToShift)
修改后的完整代码
private XSSFRow copyRow(XSSFSheet worksheet, int parentRowNum, int destinationRowNum) { // Get the source / new row XSSFRow newRow = worksheet.getRow(destinationRowNum); XSSFRow parentRow = worksheet.getRow(parentRowNum); try { int nFirstRow = destinationRowNum; int nLastRow = worksheet.getLastRowNum(); int nNumToShift = 1; //If the row exist in destination, push down all rows by 1 else create a new row if (newRow != null) { worksheet.shiftRows(nFirstRow, nLastRow, nNumToShift); // --- 新增:处理条件格式的行范围调整 --- int shiftAmount = nNumToShift; int startShiftRow = nFirstRow; // 获取所有条件格式 List<XSSFConditionalFormatting> cfList = worksheet.getConditionalFormattingList(); for (XSSFConditionalFormatting cf : cfList) { CellRangeAddress[] ranges = cf.getFormattingRanges(); for (int i = 0; i < ranges.length; i++) { CellRangeAddress range = ranges[i]; // 如果范围的起始行 >= 移位起始行,调整行号 if (range.getFirstRow() >= startShiftRow) { range.setFirstRow(range.getFirstRow() + shiftAmount); } if (range.getLastRow() >= startShiftRow) { range.setLastRow(range.getLastRow() + shiftAmount); } // 更新条件格式的范围 cf.setFormattingRanges(ranges); } } // --- 新增结束 --- } int nNumOfCell = parentRow.getLastCellNum(); int nFirstDstRow = nFirstRow + nNumToShift; int nLastDstRow = nLastRow + nNumToShift; for (int nRow = nFirstDstRow; nRow <= nLastDstRow; ++nRow) { final XSSFRow row = worksheet.getRow(nRow); if (row != null) { String msg = "Row[" + row.getRowNum() + "] is Shifted row. "; for (Cell c : row) { ((XSSFCell) c).updateCellReferencesForShifting(msg); } } } newRow = worksheet.createRow(nFirstRow); newRow.setHeight(parentRow.getHeight()); for (int i = 0; i < nNumOfCell; i++) { XSSFCell oldCell = parentRow.getCell(i); if (null != oldCell) { XSSFCell newCell = newRow.createCell(i); newCell.setCellStyle(oldCell.getCellStyle()); } } } catch (Exception e) { e.printStackTrace(); } return newRow; }
为什么这能解决问题?
Apache POI的shiftRows方法并没有处理条件格式的范围更新,这是一个已知的设计限制。通过手动遍历所有条件格式规则,调整它们的CellRangeAddress行号,就能让原来绑定在第10行的条件格式跟着移到第11行,而新插入的第10行则不会错误继承这个格式。
亲测这个方法能完美解决你遇到的问题,你可以直接把这段新增的代码加到你的方法里试试!
内容的提问来源于stack exchange,提问作者ritesh kumar poddar
相关产品推荐
相关产品推荐

