2009-12-02 149 views
23

我正在使用Apache POi HSSF库将信息导入到我的应用程序中。问题是这些文件有一些额外的/空的行需要在解析之前先被移除。使用Apache POI从Excel工作表中删除行HSSF

没有HSSFSheet.removeRow(int rowNum)方法。只有removeRow(HSSFRow row)。这个问题,空行不能被删除。例如:

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

在空行上给出NullPointerException,因为getRow()返回null。 另外,正如我在论坛上看到的,removeRow()仅擦除单元格内容,但该行仍然存在为空行。

有没有删除行(空或不),而不创建一个全新的工作表没有我想要删除的行的方式吗?

回答

0

我试图从一两年前重新回到我的大脑深处以获得与POI相关的体验,但我的第一个问题是:为什么在分析之前需要删除行?你为什么不赶上sheet.getRow(rowNum)电话的空结果并继续前进?

+0

因为我已经为格式化为简单表格的Excel文件(在第一行和下面的数据的列名称)做了解析器,如果有空行,我需要警告用户。另外,我现在要导入的文件来自另一个应用程序,并且只有很多额外的行(空或不)才能使文件看起来更漂亮! – fmaste 2009-12-02 19:23:17

+0

好的 - 但我只是说,你可能会很好地服务于子类化现有的解析器,并让你的子类忽略空行而不是对它们做某些事情;这样,来自其他应用程序的文件仍然可以很好看,而且您不必死在这些文件上。 :) – delfuego 2009-12-02 19:27:05

+0

是的。我也想到了。但该文件具有以下内容:仅用于第一列(id)的行,以及下一行中的其余列。只是因为它看起来更好。我需要把它做成一行并删除一行。 我认为我会创建一个包含工作表和行索引列表的类,并在删除行时删除索引。它很多,但我需要删除行,我不明白为什么你不能用这个库删除行! – fmaste 2009-12-02 19:36:10

3

HSSFRow有一个名为setRowNum(int rowIndex)的方法。

当您必须“删除”一行时,您将该索引放入List。然后,当您到达下一行非空时,您从该列表中获取索引并将其设置为setRowNum(),并从该列表中删除该索引。 (或者你可以使用一个队列)

2

东西沿着

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

行应该做的伎俩。

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

此解决方案在多行删除的情况下不起作用。 – gospodin 2012-11-30 18:08:39

+0

@gospodin - 在循环中运行内部代码,并且不要忘记每次删除一行时将rowIndex计数器减1。 – Avik 2014-06-20 03:15:37

+1

POI目前有一个错误会抛出> org.apache.xmlbeans.impl.values.XmlValueDisconnectedException <当在包含常见单元格的范围上多次使用此函数时 - https://bz.apache.org/bugzilla/ show_bug.cgi?id = 59733 – beermann 2016-12-02 14:41:45

6

我知道,这是一个3岁的问题,但我最近必须解决同样的问题,而且我必须在C#中完成。这里是我使用的是NPOI功能,.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

我的特殊情况(它的工作对我来说):

//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

这个答案是在AndreAY的答案的延伸,给你完成删除行的功能。

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; 
} 
相关问题