目標一樣是要把包含某些 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
沒有留言:
張貼留言