使用Apache POI 3.17第二次读取和删除行后,Excel xlsx文件损坏了

时间:2019-03-06 06:11:02

标签: java apache-poi

我正在尝试从xlsx文件读取一行,然后删除该行。 当我运行我的代码一次时,就很好了。 POI可以读取该行并删除该行。我可以使用Excel打开文件。到目前为止,一切都很好。

当我再次(第二次)重新运行代码时,POI可以读取该行并删除该行,但是当我使用excel打开文件时,我会看到

enter image description here

我遵循了hereherehere中的所有建议,但是我的问题仍然没有解决。

这是我的代码

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()方法根本没有任何文件I / O。 所有文件I / O处理均以readExcel()方法完成。

仅当我第二次运行代码时,xlsx文件才会损坏。第一次运行不会使我的文件损坏。

我想知道问题可能在哪里。

谢谢。

[更新]:
我进行了更多调查,发现一个奇怪的东西。 第一轮将做得很好。 第二次运行会将第二列从公式更改为字符串。这是快照。

enter image description here

enter image description here

由于该更改,第3次运行将引发异常

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;

不确定哪个部分未正确完成。

0 个答案:

没有答案