目標一樣是要把包含某些 key 的列全部刪掉~這次改用 Apache Poi [1] 來嘗試。
範例程式碼如下:
private static void searchRowInExcelUsingPoi (File excelFile, File excelFileNew) {
int count = 0;
FileInputStream fis = null;
FileOutputStream fos = null;
HSSFWorkbook workbook = null;
try {
fis = new FileInputStream(excelFile);
//Get the workbook instance for XLS file
workbook = new HSSFWorkbook(fis);
//Get first sheet from the workbook
HSSFSheet sheet = workbook.getSheet("test");
ArrayList<Row> list = new ArrayList<Row>();
//Get iterator to all the rows in current sheet
Iterator<Row> rowIterator = sheet.iterator();
while(rowIterator.hasNext()) {
Row row = rowIterator.next();
Iterator<Cell> cellIter = row.cellIterator();
if(cellIter.hasNext()) {
// Get the key name.
String key = row.cellIterator().next().getStringCellValue();
if(key != null && key.length() > 0) {
// Flag the row when it is found that should be removed.
if(keyMap.get(key) != null)
list.add(row);
}
}
}
// Remove the flagged row.
for(Row row: list) {
System.out.println("Remove #" + (++count) + ": " + row.cellIterator().next().getStringCellValue());
sheet.removeRow(row);
}
fos = new FileOutputStream(excelFileNew);
workbook.write(fos);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(fos != null) fos.close();
if(fis != null) fis.close();
} catch (IOException e) {}
}
}
處理過程中,因為使用 Iterator 的關係,如果直接邊掃邊刪除 Row,Java 會拋出 java.util.ConcurrentModificationException
也就是同時對同一個物件進行讀取和寫入,導致物件可能發生不一致的 Concurrent 問題。
因此這裡的處理方法是先把要刪掉的 Row 暫存到一個 ArrayList 上,然後等全掃完以後再一次進行刪除。
不過最後刪除完成的 Excel 檔,那些刪除的資料列其實都還在,只是內容變成空值了。
也許如果想把內容也刪掉,可能就要用建立新的 Sheet 的方式,把沒有被刪掉的資料列全都寫到新的 Sheet 裡吧。
但由於不知道 Apache Poi 可以保留多少資料列的排版資訊,因此這裡就沒有考慮這個作法了。
參考資料:
1、Apache POI - the Java API for Microsoft Documents
2、Read / Write Excel File In Java Using Apache POI
沒有留言:
張貼留言