亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

獲取行索引時出現 XmlValueDisconnectedException

獲取行索引時出現 XmlValueDisconnectedException

萬千封印 2023-04-19 16:08:34
在我的代碼中,我逐行檢查一個 XLSX 文件,并使用 Apache POI 4.1.0 對數據庫進行驗證。如果我發現不正確的行,我會通過將其添加到List<XSSFRow> toRemove. 在遍歷每一行之后,這個小方法應該刪除標記為刪除的行:ListIterator<XSSFRow> rowIterator = toRemove.listIterator(toRemove.size());while (rowIterator.hasPrevious()) {    XSSFRow row = rowIterator.previous();    if (row != null && row.getSheet() == sheet) {        int lastRowNum = sheet.getLastRowNum();        int rowIndex = row.getRowNum();        if (rowIndex == lastRowNum) {            sheet.removeRow(row);        } else if (rowIndex >= 0 && rowIndex < lastRowNum) {            sheet.removeRow(row);        } else {            System.out.println("\u001B[31mERROR: Removal failed because row " + rowIndex + " is out of bounds\u001B[0m");        }        System.out.println("Row " + rowIndex + " successfully removed");    } else {        System.out.println("Row skipped in removal because it was null already");    }}getRowNum()但由于某些未知原因,它完美地刪除了所有行,然后在獲取最后(第一個添加的)行的行索引 ( ) 時拋出 XmlValueDisconnectedException 。Stacktrace的相關部分: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:400)    at Overview.removeRows(Overview.java:122)編輯:我也嘗試更改迭代過程(見下文)但錯誤保持不變。for (XSSFRow row : toRemove) {   // same code as above without iterator and while}
查看完整描述

1 回答

?
偶然的你

TA貢獻1841條經驗 獲得超3個贊

如果一行在 List 中被雙重包含,則會發生錯誤toRemove。AList允許重復條目。所以同一行可能會被雙重添加到List. 如果然后Iterator得到該行的第一次出現,這將從工作表中正確刪除。但是,如果稍后再次出現同一行,則row.getRowNum()失敗,因為該行不再存在于工作表中。


這是重現該行為的完整代碼:


import org.apache.poi.ss.usermodel.*;


import java.io.FileInputStream;

import java.io.FileOutputStream;


import java.util.*;


public class ExcelRemoveRows {


 public static void main(String[] args) throws Exception {


  String filePath = "Excel.xlsx"; // must contain at least 5 filled rows


  Workbook workbook = WorkbookFactory.create(new FileInputStream(filePath));

  Sheet sheet = workbook.getSheetAt(0);


  List<Row> toRemoveList = new ArrayList<Row>();

  toRemoveList.add(sheet.getRow(0));

  toRemoveList.add(sheet.getRow(2));

  toRemoveList.add(sheet.getRow(4));

  toRemoveList.add(sheet.getRow(2)); // this produces the error


  System.out.println(toRemoveList); // contains row hawing index 2 (r="3") two times


  for (Row row : toRemoveList) {

   System.out.println(row.getRowNum()); // XmlValueDisconnectedException on second occurance of row index 2

   sheet.removeRow(row);

  }


  FileOutputStream out = new FileOutputStream("Changed"+filePath);

  workbook.write(out);

  out.close();

  workbook.close();

 }

}

解決方案是避免List多次包含同一行。


我不會收集要在 a 中刪除的行List<XSSFRow>,而是收集要在 a 中刪除的行號Set<Integer>。這將避免重復,因為 aSet不允許重復的元素。然后要刪除的行可以簡單地通過sheet.getRow(rowNum).


代碼:


...

  Set<Integer> toRemoveSet = new HashSet<Integer>();

  toRemoveSet.add(sheet.getRow(0).getRowNum());

  toRemoveSet.add(sheet.getRow(2).getRowNum());

  toRemoveSet.add(sheet.getRow(4).getRowNum());

  toRemoveSet.add(sheet.getRow(2).getRowNum());


  System.out.println(toRemoveSet); // does not contain the row index 2 two times


  for (Integer rowNum : toRemoveSet) {

   Row row = sheet.getRow(rowNum);

   System.out.println(row.getRowNum());

   sheet.removeRow(row);

  }

...


查看完整回答
反對 回復 2023-04-19
  • 1 回答
  • 0 關注
  • 1412 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號