使用Apache POI HSSF从Excel工作表中删除一行

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

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

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

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

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

  /** * 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); } } } 

我知道,这是一个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); } } 

HSSFRow有一个名为setRowNum(int rowIndex)

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

东西沿线

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

应该做的伎俩。

我的特例(对我有用):

  //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); } } } } } } } 

我试图从一两年前回到我的脑海深处,以获得与POI相关的经验,但是我的第一个问题是:为什么在解析之前需要删除行? 你为什么不抓住sheet.getRow(rowNum)调用的空结果并继续?

这个答案是对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; }