【问题标题】:Sort excel by a column using shiftRows- Apache POI - XmlValueDisconnectedException使用 shiftRows-Apache POI-XmlValueDisconnectedException 按列对 excel 进行排序
【发布时间】:2019-12-12 20:50:13
【问题描述】:

我有一个XSSFWorkbook,有 n 个列。我的要求是按第一列对整个工作表进行排序。 我提到了这个link,但没有得到任何关于排序的信息。

我也尝试过 here 的代码,但它在

处给出异常
sheet.shiftRows(row2.getRowNum(), row2.getRowNum(), -1);

我正在使用Apache POI 3.17

有人有什么建议或解决办法吗?

【问题讨论】:

    标签: java excel apache-poi


    【解决方案1】:

    移动列时 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)
    ...
    

    我认为它与您的情况相同。所以我想出了另一种方法:

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

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

    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++;
        }
    }
    

    我在下面的文件上试了一下

       A      B
    ---------------
    Header1 Header2
    a       one
    c       three
    d       four
    b       two
    

    它是这样排序的:

       A      B
    ---------------
    Header1 Header2
    a       one
    b       two
    c       three
    d       four
    

    【讨论】:

    • 我想忽略标题行以进行排序。在这种情况下我应该怎么做? @Bentaye
    • 标题只有一行?
    • 是的。现在它只有一个。所以基本上我想根据第一列对数据进行排序,但从第二行开始@Bentaye
    • 谢谢@Bentaye .. 它对我有用.. 我已经申请 if cond in for 循环来处理这个问题,这也很好.. 谢谢 :)
    • @Dolly 太好了,如果一切顺利,您可以接受答案
    猜你喜欢
    • 2012-10-19
    • 2017-02-23
    • 1970-01-01
    • 1970-01-01
    • 2011-03-13
    • 1970-01-01
    • 1970-01-01
    • 2020-09-29
    • 2017-08-05
    相关资源
    最近更新 更多