话不多说 直接上代码 主要思路是将合并单元格格式删除 处理完行后 再将合并单元格根据情况创建出来
public class POIDelete {
private static final Logger log = LoggerFactory.getLogger(POIDelete.class);
@Test
public void delete(){
String fileName = "文件路径(E:\\failName)";
String sheetName = "工作薄名称";
int rowIndex = 11; // 要删除的行索引
try {
deleteRowWithMergedCells(fileName,sheetName,rowIndex);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 删除指定行
* @param fileName
* @param sheetName
* @param rowIndex
* @throws Exception
*/
public static void deleteRowWithMergedCells(String fileName,String sheetName, int rowIndex) throws Exception{
FileInputStream file = new FileInputStream(fileName);
Workbook workbook = WorkbookFactory.create(file);//获取工作薄
Sheet sheet = workbook.getSheet(sheetName);//获取器工作页
Row row = sheet.getRow(rowIndex);
if (row != null) {
if (hasCellsInRow(row)){
System.out.println("指定行中包含单元格");
//获取指定行在那些合并合并单元格里
List<CellRangeAddress> mergedRegionsInRow = getMergedRegionsInRow(sheet, rowIndex);
int [] rows;
int firstRow;
int firstColumn;
String stringCellValue;
for (int i = 0;i<mergedRegionsInRow.size();i++){
//直接把要操作的行其中的单元格给删除
for (int j = sheet.getNumMergedRegions() - 1; j >= 0; j--) {
CellRangeAddress mergedRegion = sheet.getMergedRegion(j);
// 检查合并单元格是否包含指定的行索引
if (mergedRegion.getFirstRow() <= rowIndex && mergedRegion.getLastRow() >= rowIndex) {
sheet.removeMergedRegion(j); // 移除合并单元格
}
}
firstRow = mergedRegionsInRow.get(i).getFirstRow();
if (rowIndex == firstRow){//说明要删除的行是这个合并单元格的第一行
//将这一行的数据复制到下一行
firstColumn = mergedRegionsInRow.get(i).getFirstColumn();
stringCellValue = row.getCell(firstColumn).getStringCellValue();
//将数据复制到第二行
int nextRowIndex = rowIndex + 1;
Cell nextCell = sheet.getRow(nextRowIndex).getCell(firstColumn);
//根据具体的单元格类型进行复制
// nextCell.setCellValue(stringCellValue);
Cell cell = row.getCell(firstColumn);
CellType cellType = row.getCell(firstColumn).getCellTypeEnum();
if (cellType == CellType.STRING) {
stringCellValue = cell.getStringCellValue();
nextCell.setCellValue(stringCellValue);
} else if (cellType == CellType.NUMERIC) {
double numericCellValue = cell.getNumericCellValue();
nextCell.setCellValue(numericCellValue);
} else if (cellType == CellType.BOOLEAN) {
boolean booleanCellValue = cell.getBooleanCellValue();
nextCell.setCellValue(booleanCellValue);
} else if (cellType == CellType.FORMULA) {
String formula = cell.getCellFormula();
nextCell.setCellFormula(formula);
}
}
}
//删除本行 一这一行
sheet.removeRow(row);
sheet.shiftRows(rowIndex + 1, sheet.getLastRowNum(), -1);
//移动后本单元格的格式就乱了 在根据获取的本单元格信息 再创建一个新的单元格
for (int i = 0;i<mergedRegionsInRow.size();i++){
CellRangeAddress cellRangeAddress = mergedRegionsInRow.get(i);
sheet.addMergedRegion(new CellRangeAddress(cellRangeAddress.getFirstRow(), cellRangeAddress.getLastRow()-1, cellRangeAddress.getFirstColumn(), cellRangeAddress.getLastColumn()));
}
}else {
System.out.println("指定行中不包含单元格");
// 删除指定行
sheet.removeRow(row);
sheet.shiftRows(rowIndex + 1, sheet.getLastRowNum(), -1);
}
}
file.close();
FileOutputStream outFile = new FileOutputStream(fileName);
workbook.write(outFile);
outFile.close();
System.out.println("执行完成");
}
//判断指定航有没有合并单元格
public static boolean hasCellsInRow(Row row) {
if (row == null) {
return false;
}
int lastCellNum = row.getLastCellNum();
return lastCellNum >= 0;
}
//获取指定行做在的合并单元格的信息
private static List<CellRangeAddress> getMergedRegionsInRow(Sheet sheet, int rowIndex) {
List<CellRangeAddress> mergedRegions = new ArrayList<>();
for (CellRangeAddress mergedRegion : sheet.getMergedRegions()) {
int firstRow = mergedRegion.getFirstRow();
int lastRow = mergedRegion.getLastRow();
if (rowIndex >= firstRow && rowIndex <= lastRow) {
mergedRegions.add(mergedRegion);
}
}
return mergedRegions;
}
}
只是一种解决方法 大家有更好的可以一起讨论