0

I am trying to read a row from xlsx file and then remove the row. When I run my code once , it is perfectly fine. POI can read the row and remove the row. I can open the file using Excel. So far so good.

When I re-run my code once again (second time), POI can read the row and remove the row, but when I open the file using excel I see

enter image description here

I followed all suggestions in here , here , and here , but my problem still doesn't get solved.

This is my codes

public static void main(String[] args) throws InvalidFormatException, IOException {
        new ExcelReader().readExcel(PATH_TO_EXCEL, Constants.sheetName);
        }

private void readExcel(String pathToExcel , String sheetName) throws InvalidFormatException {

        Sheet sheet = null;
        try {
            FileInputStream fileInput = new FileInputStream(new File(pathToExcel));
            Workbook workbook = WorkbookFactory.create(fileInput);

            Iterator<Sheet> sheetItr = workbook.sheetIterator();
            while (sheetItr.hasNext()) {
                sheet = sheetItr.next();
                // For Users sheet create List of objects
                if (sheet.getSheetName().equals(sheetName)) {
                    readExcelSheet(sheet);
                } else {
                    // For other sheet just print the cell values
                    System.out.println("Sheet not available");
                }
            }

            //Now it's time to delete the row that we have just read
            removeAndShiftRow(PATH_TO_EXCEL,1,true, sheet);
            fileInput.close();

            FileOutputStream outFile = new FileOutputStream(new File(pathToExcel));
            workbook.write(outFile);
            outFile.flush();
            outFile.close();
            workbook.close();


        } catch (EncryptedDocumentException | IOException | ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


private void readExcelSheet(Sheet sheet) throws ParseException, IOException {
        System.out.println("Starting to read sheet- " + sheet.getSheetName());
        Iterator<Row> rowItr = sheet.iterator();
        List<User> userList = new ArrayList<>();
        DataFormatter formatter = new DataFormatter();
        // Iterate each row in the sheet
        while (rowItr.hasNext()) {
            User user = new User();
            Row row = rowItr.next();
            // First row is header so skip it
            if (row.getRowNum() == 0) {
                continue;
            } else if (row.getCell(1) == null || row.getCell(1).getCellTypeEnum().equals(CellType.BLANK)) {
                continue;
            } else if (formatter.formatCellValue(row.getCell(0)).equals("USED")) {
                continue;
            } else {
                Iterator<Cell> cellItr = row.cellIterator();
                // Iterate each cell in a row
                while (cellItr.hasNext()) {

                    Cell cell = cellItr.next();
                    int index = cell.getColumnIndex();
                    switch (index) {
                        case 0:
                            System.out.println(formatter.formatCellValue(cell));
                            user.setIDNumber(formatter.formatCellValue(cell));
                            //sheet.createRow(row.getRowNum()).createCell(0).setCellValue("USED");
                            break;
                        case 1:
                            System.out.println(cell.getRichStringCellValue());
                            user.setIDNumberShort(formatter.formatCellValue(cell));
                            cell.setCellValue("used");
                            break;
                        case 2:
                            System.out.println(formatter.formatCellValue(cell));
                            user.setID(formatter.formatCellValue(cell));
                            cell.setCellValue("used");
                            break;
                        case 3:
                            System.out.println(formatter.formatCellValue(cell));
                            user.setEmail(formatter.formatCellValue(cell));
                            cell.setCellValue("used");
                            break;
                        case 4:
                            System.out.println(formatter.formatCellValue(cell));
                            user.setFirstName(formatter.formatCellValue(cell));
                            cell.setCellValue("used");
                            break;
                        case 5:
                            System.out.println(formatter.formatCellValue(cell));
                            user.setLastName(formatter.formatCellValue(cell));
                            cell.setCellValue("used");
                            break;
                        case 6:
                            System.out.println(formatter.formatCellValue(cell));
                            user.setGender(formatter.formatCellValue(cell));
                            cell.setCellValue("used");
                            break;
                        case 7:
                            System.out.println(formatter.formatCellValue(cell));
                            user.setHomePhone(formatter.formatCellValue(cell));
                            cell.setCellValue("used");
                            break;
                        case 8:
                            System.out.println(formatter.formatCellValue(cell));
                            user.setMobile(formatter.formatCellValue(cell));
                            cell.setCellValue("used");
                            break;
                        case 9:
                            System.out.println(formatter.formatCellValue(cell));
                            user.setDOB(formatter.formatCellValue(cell));
                            cell.setCellValue("used");
                            break;
                        case 10:
                            System.out.println(formatter.formatCellValue(cell));
                            user.setAddress(formatter.formatCellValue(cell));
                            cell.setCellValue("used");
                            break;
                    }
                }
                userList.add(user);
                System.out.println("xxxxxxx");
                System.out.println(row.getRowNum());
                //removeRow(sheet, row.getRowNum());
                //this.deleteRow(row, sheet , WorkbookFactory.create(new FileInputStream(PATH_TO_EXCEL)));
                break;
            }
        }
        for (User user : userList) {
            System.out.println(user.getFirstName() + " " + user.getLastName() + " " + user.getEmail() + " " + user.getDOB());
        }

    }


private static void removeAndShiftRow(String pathToExcel, int rowToBeRemoved, boolean removeIndexOneOnly, Sheet sheet) throws IOException, InvalidFormatException {

        if (removeIndexOneOnly == true) {
            rowToBeRemoved = 1;

        }
        int lastRowNum = sheet.getLastRowNum();
        Row row = sheet.getRow(rowToBeRemoved);
        if (row != null && rowToBeRemoved != lastRowNum) {
            //System.out.println(row.getCell(3).getRichStringCellValue()); //For Testing
            //System.out.println(row.getCell(4).getRichStringCellValue()); //For Testing
            System.out.println("row to be removed " + rowToBeRemoved);
            System.out.println("last row " + lastRowNum);

            sheet.removeRow(row);
            sheet.shiftRows(rowToBeRemoved + 1, lastRowNum, -1);
            //sheet.getWorkbook().setActiveSheet(sheet.getWorkbook().getSheetIndex(sheet));
        }

        if (rowToBeRemoved == lastRowNum) {
            System.out.println("Very Last Row");
            Row removingRow = sheet.getRow(rowToBeRemoved);
            if (removingRow != null) {
                sheet.removeRow(removingRow);
            }
        }
    }

removeAndShiftRow() method does not have any file I/O at all. All file I/O process is done in readExcel() method.

The xlsx file gets corrupted only when I run my codes for the 2nd time. The 1st run will not make my file corrupted.

I am wondering where could be the issue.

Thanks.

[Update]:
I do some more investigation and I found a weird thing. The 1st run will just do perfectly fine. The 2nd run will change my second column from formula to string. Here is the snapshot.

enter image description here

enter image description here

Because of that change, the 3rd run will throw exception

Exception in thread "main" java.lang.IllegalStateException: Master cell of a shared formula with sid=0 was not found
at org.apache.poi.xssf.usermodel.XSSFCell.convertSharedFormula(XSSFCell.java:507)
at org.apache.poi.xssf.usermodel.XSSFCell.getCellFormula(XSSFCell.java:491)
at org.apache.poi.xssf.usermodel.XSSFCell.getCellFormula(XSSFCell.java:469)
at org.apache.poi.ss.usermodel.DataFormatter.formatCellValue(DataFormatter.java:984)
at org.apache.poi.ss.usermodel.DataFormatter.formatCellValue(DataFormatter.java:944)
at org.apache.poi.ss.usermodel.DataFormatter.formatCellValue(DataFormatter.java:923)
at Sandbox.ExcelReader.readExcelSheet(ExcelReader.java:110)

The exception points to method readExcelSheet() specifically this line

 case 1:
         System.out.println(cell.getRichStringCellValue());
         user.setIDNumberShort(formatter.formatCellValue(cell)); //This will throw exception in the 3rd run
         cell.setCellValue("used");
         break;

Not sure which part is not done correctly.

keylogger
  • 822
  • 3
  • 19
  • 39
  • 1
    are there any exceptions happening the second time you run your program? maybe the in/outputstreams dont get closed properly. have you already tried opening them via try-with-ressource? – ChristophE Mar 06 '19 at 06:22
  • 2
    I've tried to reproduce your problem. But in my Machine it works - the file is not corrupted. You did not provide the implementation of the methods: removeAndShiftRow, readExcelSheet. Please provide your implementation, for further investigation. – Shahar Rotshtein Mar 06 '19 at 06:59
  • Thanks ChristophE and Shahar. No there is no exception thrown at all the 2nd time I run my codes. In fact, when I force Excel to repair it and open the file, the file looks like what I expected. Happy with the output. It is just corrupted. I have attached my `removeAndShiftRow()` and `readExcelSheet()`. These methods are just normal logic without any file I/O activities. Thanks :) – keylogger Mar 06 '19 at 07:33
  • close the Excel File then run the program. – Ng Sharma Mar 06 '19 at 07:49
  • I always close the excel before running the codes. Otherwise, it would throw exception. – keylogger Mar 06 '19 at 09:26
  • I added some more investigation results from today. Thanks :) – keylogger Mar 06 '19 at 22:17
  • 1
    `Master cell of a shared formula with sid=0 was not found`: That means, in the originally sheet in `B2` was a formula `=RIGHT(A2,9)` used and filled downwards. There Excel's GUI has chosen using a shared formula instead of putting the same formula in all cells. A shared formula means, only `B2` contans the formula itself, `B3` contains the master formula having `RIGHT(A3,9)` and `B4:B[n]` only contain references to that master formula by `si`. Now, if you delete `B3`, this master formula is gone. – Axel Richter Mar 07 '19 at 06:26
  • 1
    So it seems `apache poi` does not handle such shared formulas properly while removing rows. – Axel Richter Mar 07 '19 at 06:26
  • Thanks Axel. `B2` contains the original formula. `B3` contains master formula. `B4 and the rests` only contain reference to `B3`. How come `B3` contains master formula? The way I did was I wrote the formula in `B2` , then copied and pasted it to `B3 and the rests`. So, shouldn't `B3 and the rests` contain reference to the original `B2` ? I don't quite understand how excel works. Thanks. – keylogger Mar 07 '19 at 09:19
  • 1
    "I don't quite understand how excel works.": Well, sometimes nobody understand `Microsoft`' s decisions ;-). But `*.xlsx` files are simple `ZIP` archives. So one can unzip them and have a look into. Do that and look at `/xl/worksheets/sheet[n].xml` then you will see. – Axel Richter Mar 07 '19 at 16:37

0 Answers0