2009-12-02 5 views
23

Ich verwende die Apache POi HSSF-Bibliothek, um Informationen in meine Anwendung zu importieren. Das Problem ist, dass die Dateien einige extra/leere Zeilen haben, die zuerst vor dem Parsen entfernt werden müssen.Entfernen einer Zeile aus einer Excel-Tabelle mit Apache POI HSSF

Es gibt keine HSSFSheet.removeRow(int rowNum) Methode. Nur removeRow(HSSFRow row). Das Problem dabei ist, dass leere Zeilen nicht entfernt werden können. Zum Beispiel:

sheet.removeRow(sheet.getRow(rowNum)); 

gibt eine Nullpointer auf leere Zeilen, weil getRow() gibt null zurück. Auch, wie ich in Foren lesen, löscht nur den Zelleninhalt, aber die Zeile ist immer noch da eine leere Zeile.

Gibt es eine Möglichkeit, Zeilen (leer oder nicht) zu entfernen, ohne ein ganzes neues Blatt ohne die Zeilen zu erstellen, die ich entfernen möchte?

Antwort

0

Ich versuche, vor ein oder zwei Jahren wieder in die Tiefe meines Gehirns für meine POI-bezogene Erfahrung zu gelangen, aber meine erste Frage wäre: Warum müssen die Reihen vor dem Parsen entfernt werden? Warum fangen Sie nicht einfach das Null-Ergebnis vom sheet.getRow(rowNum) Anruf ein und machen weiter?

+0

Da ich bereits einen Parser für Excel-Dateien, die als eine einfache Tabelle (Spaltennamen in der ersten Zeile und Daten unten) formatiert sind, und ich brauche, um den Benutzer zu warnen, wenn es leere Zeilen sind. Außerdem sind die Dateien, die ich jetzt importieren möchte, aus einer anderen Anwendung und haben viele zusätzliche Zeilen (leer oder nicht), nur um die Datei schöner aussehen zu lassen! – fmaste

+0

OK - Ich würde nur sagen, dass Sie wahrscheinlich gut bedient sind, nur um Ihren vorhandenen Parser abzuleiten und Ihre Unterklasse leere Zeilen ignorieren zu lassen, anstatt etwas damit zu tun; Auf diese Weise können die Dateien von der anderen App immer noch gut aussehen und Sie müssen nicht auf diesen Dateien sterben. :) – delfuego

+0

Ja. Daran denke ich auch. Aber die Datei hat Dinge wie: eine Zeile nur für die erste Spalte (die ID) und den Rest der Spalten in der Zeile darunter. Nur weil es schöner aussieht. Ich muss es eine Zeile machen und löschen. Ich denke, dass ich eine Klasse erstellen würde, die ein Blatt und eine Liste von Zeilenindizes enthält, und lösche die Indizes, wenn ich eine Zeile lösche. Es ist zu viel, aber ich muss Zeile löschen, ich verstehe nicht, warum Sie Zeile mit dieser Bibliothek nicht löschen können! – fmaste

3

Die HSSFRow hat eine Methode namens setRowNum(int rowIndex). Wenn Sie eine Zeile löschen müssen, fügen Sie diesen Index in eine List ein. Wenn Sie dann zur nächsten nicht leeren Zeile gelangen, nehmen Sie einen Index aus dieser Liste und setzen ihn auf setRowNum() und entfernen den Index aus dieser Liste. (Sie können auch eine Warteschlange verwenden)

2

Etwas nach dem Vorbild von

int newrownum=0; 
for (int i=0; i<=sheet.getLastRowNum(); i++) { 
    HSSFRow row=sheet.getRow(i); 
    if (row) row.setRowNum(newrownum++); 
} 

sollte es tun.

24
/** 
* Remove a row by its index 
* @param sheet a Excel sheet 
* @param rowIndex a 0 based index of removing row 
*/ 
public static void removeRow(HSSFSheet sheet, int rowIndex) { 
    int lastRowNum=sheet.getLastRowNum(); 
    if(rowIndex>=0&&rowIndex<lastRowNum){ 
     sheet.shiftRows(rowIndex+1,lastRowNum, -1); 
    } 
    if(rowIndex==lastRowNum){ 
     HSSFRow removingRow=sheet.getRow(rowIndex); 
     if(removingRow!=null){ 
      sheet.removeRow(removingRow); 
     } 
    } 
} 
+1

Diese Lösung funktioniert nicht im Fall des Löschens mehrerer Zeilen. – gospodin

+0

@gospodin - Führen Sie den Inside-Code in einer Schleife aus und vergessen Sie nicht, den rowIndex-Zähler jedes Mal um 1 zu verringern, wenn Sie eine Zeile löschen. – Avik

+1

Derzeit gibt es einen Fehler im POI, der> org.apache.xmlbeans.impl.values.XmlValueDisconnectedException beermann

6

Ich weiß, das ist eine 3 Jahre alte Frage, aber ich hatte das gleiche Problem vor kurzem zu lösen, und ich hatte es in C# zu tun. Und hier ist die Funktion, die ich mit NPOI bin mit, .Net 4,0

public static void DeleteRow(this ISheet sheet, IRow row) 
    { 
     sheet.RemoveRow(row); // this only deletes all the cell values 

     int rowIndex = row.RowNum; 

     int lastRowNum = sheet.LastRowNum; 

     if (rowIndex >= 0 && rowIndex < lastRowNum) 
     { 
      sheet.ShiftRows(rowIndex + 1, lastRowNum, -1); 
     } 
    } 
1

Mein besonderer Fall (es für mich gearbeitet):

//Various times to delete all the rows without units 
    for (int j=0;j<7;j++) { 
     //Follow all the rows to delete lines without units (and look for the TOTAL row) 
     for (int i=1;i<sheet.getLastRowNum();i++) { 
     //Starting on the 2nd row, ignoring first one 
     row = sheet.getRow(i); 
     cell = row.getCell(garMACode); 
     if (cell != null) 
     { 
      //Ignore empty rows (they have a "." on first column) 
      if (cell.getStringCellValue().compareTo(".") != 0) { 
      if (cell.getStringCellValue().compareTo("TOTAL") == 0) { 
       cell = row.getCell(garMAUnits+1); 
       cell.setCellType(HSSFCell.CELL_TYPE_FORMULA); 
       cell.setCellFormula("SUM(BB1" + ":BB" + (i - 1) + ")"); 
      } else { 
       cell = row.getCell(garMAUnits); 
       if (cell != null) { 
       int valor = (int)(cell.getNumericCellValue()); 
       if (valor == 0) { 
        //sheet.removeRow(row); 
        removeRow(sheet,i); 
       } 
       } 
      } 
      } 
     } 
     } 
    } 
0

Diese Antwort ist eine Erweiterung über AndreAY Antwort, Sie geben vollständige Funktion zum Löschen einer Zeile.

public boolean deleteRow(String sheetName, String excelPath, int rowNo) throws IOException { 

    XSSFWorkbook workbook = null; 
    XSSFSheet sheet = null; 

    try { 
     FileInputStream file = new FileInputStream(new File(excelPath)); 
     workbook = new XSSFWorkbook(file); 
     sheet = workbook.getSheet(sheetName); 
     if (sheet == null) { 
      return false; 
     } 
     int lastRowNum = sheet.getLastRowNum(); 
     if (rowNo >= 0 && rowNo < lastRowNum) { 
      sheet.shiftRows(rowNo + 1, lastRowNum, -1); 
     } 
     if (rowNo == lastRowNum) { 
      XSSFRow removingRow=sheet.getRow(rowNo); 
      if(removingRow != null) { 
       sheet.removeRow(removingRow); 
      } 
     } 
     file.close(); 
     FileOutputStream outFile = new FileOutputStream(new File(excelPath)); 
     workbook.write(outFile); 
     outFile.close(); 


    } catch(Exception e) { 
     throw e; 
    } finally { 
     if(workbook != null) 
      workbook.close(); 
    } 
    return false; 
} 
Verwandte Themen