我有用户提供的 excel 文件需要转换为 PDF。使用 excel interop,我可以使用 .ExportAsFixedFormat()
很好地完成这项工作。当工作簿有数百万行时,我的问题就出现了。这变成了一个有 50k+ 页的文件。如果工作簿在所有这些行中都有内容,那就没问题了。但是,每次出现其中一个文件时,可能有 50 行包含内容,其余为空白。我怎样才能删除空行,以便将其导出为合适大小的 PDF?
我尝试从最后一行开始,逐一使用
CountA
检查该行是否有内容,如果有,则将其删除。这不仅需要永远,而且在大约 10 万行后似乎会失败,并出现以下错误:无法评估表达式,因为代码已优化或 native 框架位于调用堆栈的顶部。
我试过使用
SpecialCells(XlCellType.xlCellTypeLastCell, XlSpecialCellsValue.xlTextValues)
但如果任何单元格具有格式(如背景颜色),它会包含一行。我试过使用
<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/