如何使用NPOI和C#删除空行并减少excel中的总行数

时间:2017-01-17 15:30:53

标签: c# npoi

我正在尝试使用带有C#的npoi删除excel文件中的空行。我正面临着我的代码问题可以请任何人帮忙。

public static void removeRow(string filepath,string SheetName) 
    {
    try {
            IWorkbook workBook = WorkbookFactory.Create(new FileStream(
                          Path.GetFullPath(filepath),
                          FileMode.Open, FileAccess.Read,
                          FileShare.ReadWrite));
            ISheet workSheet = workBook.GetSheet(SheetName);
            int lastRowNum = workSheet.LastRowNum;
            for (int i = 0; i < lastRowNum; i++)
            {
                string value = ExcelUtils.getCellData(filepath, SheetName, i, 1);
                if (value.Equals(""))
                {
                    workSheet.ShiftRows(i + 1, lastRowNum, -1);
                    lastRowNum = workSheet.LastRowNum;
                    i--;
                    using (FileStream stream = new FileStream(filepath, FileMode.Create, FileAccess.ReadWrite))
                    {
                        workBook.Write(stream);
                        stream.Close();
                    }
                }
            }


        }
        catch (Exception e)
        {
            Console.WriteLine("Unable to get Data from Sheet. Exception is : " + e);
        }
    }

我的问题是当在工作单workSheet.ShiftRows()方法中找到一个空行时,向上移动空行然后lastRowNum(工作表中的总行数)减少1.它第一次工作,但是当下一次空行时发现lastRownum值正在增加但不会减少。

3 个答案:

答案 0 :(得分:0)

我不熟悉NPOI,但是看一下你的代码,有些东西看起来很奇怪或有问题。首先是如果行为空则递减i。这似乎很奇怪,因为i是你的for循环计数器变量而lastRowNum是你在循环中也改变的结束条件。所以一个示例传递将是:假设第一个空行是第3行(当i = 2时)。循环前两行然后我们将第3行清空。所以i = 2,而lastRowNum没有改变,让我们说最后一行是10.所以我们输入if (value.Equals(""))因为该行是空的。我猜你把第i + 1行移到空行3所在的i。然后重置lastRowNum应该是9.然后减去i ????。我相信你这样做的原因是因为在第3行删除的行现在是第4行的行。所以你需要再次重新检查第3行。

for循环看起来有点奇怪......每次找到空行时,递减i并重新设置新的lastRowNum?这两个变量都控制for循环,并且在循环中更改这些变量会导致意外结果。

由于我对NPOI并不熟悉,因此很难推荐使用NPOI的更好方法,但我之前已经看过这个,看起来简单易用的解决方案可能会起作用。由于每次删除行时范围和行索引都会更改,因此从上到下删除时必须考虑这些更改。我建议你尝试从BOTTOM UP中删除行。如果从底部开始并进行处理,则无需更改lastRowNum变量,因为它只是一个起点。此外,当您从下往上删除行时,您不必在循环中重新移动i索引。我会尝试这个,看看它是否让事情变得更容易。希望这会有所帮助。

答案 1 :(得分:0)

我在Java中解决了同样的问题但在C#中没有解决。这是我删除空行的java代码。

public static void removeRow(String SheetName) throws Exception {
    try {
    FileInputStream fis = new FileInputStream(sPathTestData);
    ExcelWsheet = ExcelWbook.getSheet(SheetName);
    int lastRowNum=ExcelWsheet.getLastRowNum();
    for(int i=0; i<lastRowNum;i++)
        {
        String value =ExcelUtils.getCellData(i, 1, "Sheet1");
         if(value.equals("")){
            ExcelWsheet.shiftRows(i+1,lastRowNum, -1);
            lastRowNum=ExcelWsheet.getLastRowNum();
            i--;
         }
        }
        fis.close();
        FileOutputStream fileOut = new FileOutputStream(sPathTestData);
        ExcelWbook.write(fileOut);
        fileOut.flush();
        fileOut.close();
      } 
catch(FileNotFoundException fe){fe.printStactTrace();}  
    }

答案 2 :(得分:0)

这里没什么新东西...我只是用这些

 private void ExcelRemoveRows(ISheet sheet, int rowNoFrom, int rowNoTo)
        {
            int nRowToRemove = rowNoTo - rowNoFrom + 1;
            for (int k = 1; k <= nRowToRemove; k++)
            {
                sheet.RemoveRow(sheet.GetRow(rowNoFrom));
                int lastRow = sheet.LastRowNum;
                sheet.ShiftRows(rowNoFrom + 1, lastRow, -1);
            }
        }