简体   繁体   中英

Remove Specific row Apache Poi

I need to remove row that contains word that user inputs. Here my code:

        try {
            System.out.println("Write material that need to be removed: ");
            Scanner in = new Scanner(System.in);
            String toFind = in.nextLine();
            FileInputStream file = new FileInputStream(new File("solty.xls"));

            //Create Workbook instance holding reference to .xlsx file
            HSSFWorkbook workbook = new HSSFWorkbook(file);
            DataFormatter formatter = new DataFormatter();
            HSSFSheet sheet = workbook.getSheetAt(0);

            for (Row row : sheet) {
                for (Cell cell : row) {
                    Iterator<Row> rowIterator = sheet.iterator();

                    while (rowIterator.hasNext()) {
                        Row row3 = rowIterator.next();
                        CellReference cellRef = new CellReference(row3.getRowNum(), cell.getColumnIndex());
                        
                        String text = formatter.formatCellValue(cell);

                        // is it an exact match?
                        if (toFind.equals(text)) {
                            System.out.println("Text finded at " + cellRef.formatAsString());
                            System.out.println(cellRef.getRow());
                            int rowIndex = cellRef.getRow();
                            System.out.println(row.getCell(rowIndex));
                            HSSFRow row1 = sheet.getRow(rowIndex);
                            sheet.removeRow(row1);
                            file.close();
                            FileOutputStream outFile = new FileOutputStream(new File("solty.xls"));
                            workbook.write(outFile);
                            outFile.flush();
                            outFile.close();

                        }
                        // is it a partial match?
                        else if (text.contains(toFind)) {
                            System.out.println("Index is  " + cellRef.formatAsString());


                        }


                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

but the problem is that it deletes row consistently, not the row that contains user's word. Also even it works it has Exception: ConcurrentModificationException

The ConcurrentModificationException is thrown because Sheet.removeRow tries to change a row while a Iterator iterates over the rows of that sheet. This is not possible.

So instead of using Iterator you need to get the rows another way. For example use for loop using int r and sheet.getRow(r) to get the rows.

But Sheet.removeRow has a misleading name. It does not really removing a row but only removes the row from the sheet's storage without shifting the rows below upwards. So in fact it only totally empties the row. If you really wants removing the row, you need using Sheet.shiftRows . Sheet.shiftRows had many bugs in former versions of apache poi . So it only will work properly using current apache poi 5.0.0 .

But using Sheet.shiftRows each shifting will influence the row numbers. So the for loop using int r and sheet.getRow(r) to get the rows needs to loop backwards from bottom to top, else it will try to get row numbers which were removed already.

The following code should work using current apache poi 5.0.0 and removing all rows containing cells having String toFind as content.

import java.io.FileOutputStream;
import java.io.FileInputStream;

import org.apache.poi.ss.usermodel.*;

class RemoveSpecificRows {

 public static void main(String[] args) throws Exception {
     
  System.out.println("Write material that need to be removed: ");
  java.util.Scanner in = new java.util.Scanner(System.in);
  String toFind = in.nextLine();

  try (Workbook workbook = WorkbookFactory.create(new FileInputStream("ExcelSource.xls")); 
       FileOutputStream fileout = new FileOutputStream("ExcelResult.xls") ) {

   DataFormatter formatter = new DataFormatter();
   
   Sheet sheet = workbook.getSheetAt(0);
   
   for (int r = sheet.getLastRowNum(); r >=0;  r--) {
    Row row = sheet.getRow(r);
    if (row != null) {
     for (int c = 0; c < row.getLastCellNum(); c++) {
      Cell cell = row.getCell(c);
      String value = formatter.formatCellValue(cell);
      if (toFind.equals(value)) {
       System.out.println("Text " + toFind + " found at " + cell.getAddress()); 
       //sheet.removeRow(row); //this only empties the row
       sheet.shiftRows(r + 1, sheet.getLastRowNum() + 2, -1); //shift row below up to last row once up
       break;
      }
     }
    }      
   }

   workbook.write(fileout);

  }

 }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM