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);
}
...
添加回答
舉報