c# - 使用 Excel Interop 删除空行

标签 c# office-interop excel-interop

我有用户提供的 excel 文件需要转换为 PDF。使用 excel interop,我可以使用 .ExportAsFixedFormat() 很好地完成这项工作。当工作簿有数百万行时,我的问题就出现了。这变成了一个有 50k+ 页的文件。如果工作簿在所有这些行中都有内容,那就没问题了。但是,每次出现其中一个文件时,可能有 50 行包含内容,其余为空白。我怎样才能删除空行,以便将其导出为合适大小的 PDF?

  1. 我尝试从最后一行开始,逐一使用 CountA 检查该行是否有内容,如果有,则将其删除。这不仅需要永远,而且在大约 10 万行后似乎会失败,并出现以下错误:

    无法评估表达式,因为代码已优化或 native 框架位于调用堆栈的顶部。

  2. 我试过使用 SpecialCells(XlCellType.xlCellTypeLastCell, XlSpecialCellsValue.xlTextValues) 但如果任何单元格具有格式(如背景颜色),它会包含一行。

  3. 我试过使用 Worksheet.UsedRange 然后删除之后的所有内容,但 UsedRange 与第二点有同样的问题。

    <


这是我试过的代码:

for (int i = 0; i < worksheets.Count; i++)
{
    sheet = worksheets[i + 1];
    rows = sheet.Rows;
    currentRowIndex = rows.Count;
    bool contentFound = false;

    while (!contentFound && currentRowIndex > 0)
    {
        currentRow = rows[currentRowIndex];

        if (Application.WorksheetFunction.CountA(currentRow) == 0)
        {
            currentRow.Delete();
        }
        else
        {
            contentFound = true;
        }

        Marshal.FinalReleaseComObject(currentRow);
        currentRowIndex--;
    }

    Marshal.FinalReleaseComObject(rows);
    Marshal.FinalReleaseComObject(sheet);
}

for (int i = 0; i < worksheets.Count; i++)
{
    sheet = worksheets[i + 1];
    rows = sheet.Rows;

    lastCell = rows.SpecialCells(XlCellType.xlCellTypeLastCell, XlSpecialCellsValue.xlTextValues);
    int startRow = lastCell.Row;

    Range range = sheet.get_Range(lastCell.get_Address(RowAbsolute: startRow));
    range.Delete();

    Marshal.FinalReleaseComObject(range);
    Marshal.FinalReleaseComObject(lastCell);
    Marshal.FinalReleaseComObject(rows);
    Marshal.FinalReleaseComObject(sheet);
}

我的代码有问题吗,这是一个互操作问题,还是只是对 Excel 功能的限制?有没有更好的方法来完成我正在尝试的事情?

最佳答案

我建议您使用 CountA 获取包含某些值的行数(正如您在第 1 点中尝试过的那样)。然后将这些行复制到新工作表中并从那里导出。将几行复制到新工作表并对其进行处理比尝试从源工作表中删除大量行要容易得多。

要创建新工作表和复制行,您可以使用以下代码:

        excel.Worksheet tempSheet = workbook.Worksheets.Add();
        tempSheet.Name = sheetName;
        workbook.Save();

//创建一个复制新行的新方法

//作为行索引,您可以传递使用 CountA 找到的总行数

public void CopyRows(excel.Workbook workbook, string sourceSheetName, string DestSheetName, int rowIndex)
        {
            excel.Worksheet sourceSheet = (excel.Worksheet)workbook.Sheets[sourceSheetName];
            excel.Range source = (excel.Range)sourceSheet.Range["A" + rowIndex.ToString(), Type.Missing].EntireRow;

            excel.Worksheet destSheet = (excel.Worksheet)workbook.Sheets[DestSheetName];
            excel.Range dest = (excel.Range)destSheet.Range["A" + rowIndex.ToString(), Type.Missing].EntireRow;
            source.Copy(dest);

            excel.Range newRow = (excel.Range)destSheet.Rows[rowIndex+1];
            newRow.Insert();
            workbook.Save();
        }

关于c# - 使用 Excel Interop 删除空行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5383578/

相关文章:

c# - 具有相同列的相同表的数据建模

c# - 等到 BlockingCollection 队列被后台线程清除,如果时间太长则超时?

c# - 通过 C# 添加图片到 powerpoint 幻灯片会抛出远程过程调用失败。 (HRESULT : 0x800706BE) 的异常

c# - 使用 C# 将格式从一行复制到另一行

visual-studio-2010 - ThisWorkbook.Application.Workbooks.Open 中的 AccessViolationException

c# - visual studio 输出窗口不显示

c# - 如何: Adding Multi tables on Word with .网

c# - 关于将嵌套/分层对象的字段映射到平面列表的意见?

F# Excel Range.AutoFilter() 失败

c# - 具有服务层、业务层和 Entity Framework 的 N 层架构