Файл Excel xlsx будет поврежден после чтения и удаления строки во второй раз с использованием Apache POI 3.17 - PullRequest
0 голосов
/ 06 марта 2019

Я пытаюсь прочитать строку из файла xlsx, а затем удалить строку.Когда я запускаю свой код один раз, это прекрасно.POI может прочитать строку и удалить строку.Я могу открыть файл с помощью Excel.Все идет нормально.

Когда я снова запускаю свой код (второй раз), POI может прочитать строку и удалить ее, но когда я открываю файл с помощью Excel, я вижу

enter image description here

Я следовал всем советам в здесь , здесь и здесь , но моя проблема все еще не решена,

Это мои коды

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() метод не имеет файлового ввода-вывода вообще.Весь процесс ввода / вывода файлов выполняется методом readExcel().

Файл xlsx будет поврежден только при втором запуске кода.1-й запуск не сделает мой файл поврежденным.

Мне интересно, где может быть проблема.

Спасибо.

[Обновление]:
Я провожу еще несколько расследований и обнаружил странную вещь.1-й пробег будет просто отлично.Второй прогон изменит мой второй столбец с формулы на строку.Вот снимок.

enter image description here

enter image description here

Из-за этого изменения 3-й прогон будетthrow исключение

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)

Исключение указывает на метод readExcelSheet(), в частности, на эту строку

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

Не уверен, какая часть выполнена неправильно.

...