使用 shiftRows 按列对 Excel 进行排序- Apache POI - XmlValueDisconnectedException

Leo*_*Leo 2 java excel apache-poi

我有XSSFWorkbookn 个列。我的要求是按第一列对整个工作表进行排序。我参考了此链接,但没有获得任何有关排序的信息。

我也尝试过这里的代码,但它给出了异常

sheet.shiftRows(row2.getRowNum(), row2.getRowNum(), -1);
Run Code Online (Sandbox Code Playgroud)

我在用Apache POI 3.17

有人有什么建议或解决方案吗?

Ben*_*aye 5

移动列时 POI 似乎有一个错误,他们说它已修复,3.9但我使用过3.17并且仍然有它:

Exception in thread "main" org.apache.xmlbeans.impl.values.XmlValueDisconnectedException
at org.apache.xmlbeans.impl.values.XmlObjectBase.check_orphaned(XmlObjectBase.java:1258)
at org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.CTRowImpl.getR(Unknown Source)
at org.apache.poi.xssf.usermodel.XSSFRow.getRowNum(XSSFRow.java:394)
...
Run Code Online (Sandbox Code Playgroud)

我想你的情况是一样的。于是我想出了另外一个办法:

对行进行排序,然后创建一个新工作簿并按正确的顺序复制行。然后将此排序后的工作簿写入原始文件。

为简单起见,我假设所有单元格值都是字符串。(如果没有,则进行相应修改)

private static final String FILE_NAME = "/home/userName/Workspace/fileToSort.xlsx";

public static void main(String[] args)  {

    Workbook originalWorkbook;

    //create a workbook from your file
    try(FileInputStream excelFile = new FileInputStream(new File(FILE_NAME))) {
        originalWorkbook = new XSSFWorkbook(excelFile);
    } catch (IOException e) {
        throw new RuntimeException("Couldn't open file: " + FILE_NAME);
    }

    Sheet originalSheet = originalWorkbook.getSheetAt(0);

    // Create a SortedMap<String, Row> where the key is the value of the first column
    // This will automatically sort the rows
    Map<String, Row> sortedRowsMap = new TreeMap<>();

    // save headerRow
    Row headerRow = originalSheet.getRow(0);

    Iterator<Row> rowIterator = originalSheet.rowIterator();
    // skip header row as we saved it already
    rowIterator.next();
    // sort the remaining rows
    while(rowIterator.hasNext()) {
        Row row = rowIterator.next();
        sortedRowsMap.put(row.getCell(0).getStringCellValue(), row);
    }

    // Create a new workbook
    try(Workbook sortedWorkbook = new XSSFWorkbook();
        FileOutputStream out = new FileOutputStream(FILE_NAME)) {
        Sheet sortedSheet = sortedWorkbook.createSheet(originalSheet.getSheetName());

        // Copy all the sorted rows to the new workbook
        // - header first
        Row newRow = sortedSheet.createRow(0);
        copyRowToRow(headerRow, newRow);
        // then other rows, from row 1 up (not row 0)
        int rowIndex = 1;
        for(Row row : sortedRowsMap.values()) {
            newRow = sortedSheet.createRow(rowIndex);
            copyRowToRow(row, newRow);
            rowIndex++;
        }

        // Write your new workbook to your file
        sortedWorkbook.write(out);
    } catch (Exception e) {
        e.printStackTrace();
    }
}


// Utility method to copy rows
private static void copyRowToRow(Row row, Row newRow) {
    Iterator<Cell> cellIterator = row.cellIterator();
    int cellIndex = 0;
    while(cellIterator.hasNext()) {
        Cell cell = cellIterator.next();
        Cell newCell = newRow.createCell(cellIndex);
        newCell.setCellValue(cell.getStringCellValue());
        cellIndex++;
    }
}
Run Code Online (Sandbox Code Playgroud)

我在以下文件中尝试过

   A      B
---------------
Header1 Header2
a       one
c       three
d       four
b       two
Run Code Online (Sandbox Code Playgroud)

它是这样排序的:

   A      B
---------------
Header1 Header2
a       one
b       two
c       three
d       four
Run Code Online (Sandbox Code Playgroud)