C# 使用Excel互操作删除空行
我有用户提供的excel文件,需要转换为PDF。使用excel interop,我可以使用C# 使用Excel互操作删除空行,c#,office-interop,excel-interop,C#,Office Interop,Excel Interop,我有用户提供的excel文件,需要转换为PDF。使用excel interop,我可以使用.ExportAsFixedFormat()完成这项工作。当工作簿有数百万行时,我的问题就出现了。这将变成一个具有50k+页的文件。如果工作簿中所有这些行都有内容,那就好了。但是,每次出现其中一个文件时,可能会有50行包含内容,其余的都是空白。如何删除空行,以便将其导出为大小合适的PDF 我试着从最后一行开始,一个接一个地使用CountA检查该行是否有内容,如果有,则将其删除。这不仅要花费很长时间,而且在大
.ExportAsFixedFormat()
完成这项工作。当工作簿有数百万行时,我的问题就出现了。这将变成一个具有50k+页的文件。如果工作簿中所有这些行都有内容,那就好了。但是,每次出现其中一个文件时,可能会有50行包含内容,其余的都是空白。如何删除空行,以便将其导出为大小合适的PDF
CountA
检查该行是否有内容,如果有,则将其删除。这不仅要花费很长时间,而且在大约10万行之后似乎会失败,并出现以下错误:
无法计算表达式,因为代码已优化或本机帧位于调用堆栈顶部SpecialCells(XlCellType.xlCellTypeLastCell,XlSpecialCellsValue.xlTextValues)
,但如果任何单元格具有格式(如bg颜色),则其中包括一行工作表.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;i0)
{
currentRow=行[currentRowIndex];
if(Application.WorksheetFunction.CountA(currentRow)==0)
{
currentRow.Delete();
}
其他的
{
contentFound=true;
}
封送处理最终EleaseComObject(当前行);
当前行索引--;
}
封送处理最终EleaseComObject(行);
封送员最终电子对象(表);
}
for(int i=0;i
我的代码有问题吗?这是一个互操作问题还是仅仅是对Excel功能的限制?是否有更好的方法来执行我尝试的操作?您是否尝试过
Sheet1.Range(“A1”).CurrentRegion.ExportAsFixedFormat()
其中Sheet1是一个有效的工作表名称,“A1”是一个可以测试的单元格,以确保它位于要导出的范围内
问题是,为什么Excel认为这些“空”单元格中有数据?格式化?需要清除的预先存在的打印区域?我知道我以前也遇到过类似的情况,这是我现在唯一想到的可能性。试试这些步骤-
工作表复制到一张单独的工作表中(第2页)
如果这没有帮助,请尝试在清除格式信息的情况下重复步骤2,然后解析sheet2。您可以随时稍后复制格式信息(如果格式信息足够简单)如果您可以首先通过OleDBAdapter将Excel文件加载到数据集中,则在导入时删除空白行相对容易。。。 试试我通过堆栈溢出发布的这个
然后将数据集导出到新的Excel文件,并将该文件转换为PDF。这可能是一个很大的“如果”,当然这取决于excel的布局(或者缺少) 我今天必须解决这个问题,因为这可能是您可能的案例的一个子集 如果电子表格满足以下条件:
private static string[,] LoadCellData(Excel.Application excel, dynamic sheet)
{
int countCols = CountColsToFirstBlank(excel, sheet);
int countRows = CountRowsToFirstBlank(excel, sheet);
cellData = new string[countCols, countRows];
string datum;
for (int i = 0; i < countCols; i++)
{
for (int j = 0; j < countRows; j++)
{
try
{
if (null != sheet.Cells[i + 1, j + 1].Value)
{
datum = excel.Cells[i + 1, j + 1].Value.ToString();
cellData[i, j] = datum;
}
}
catch (Exception ex)
{
lastException = ex;
//Console.WriteLine(String.Format("LoadCellData [{1}, {2}] reported an error: [{0}]", ex.Message, i, j));
}
}
}
return cellData;
}
private static int CountRowsToFirstBlank(Excel.Application excel, dynamic sheet)
{
int count = 0;
for (int j = 0; j < sheet.UsedRange.Rows.Count; j++)
{
if (IsBlankRow(excel, sheet, j + 1))
break;
count++;
}
return count;
}
private static int CountColsToFirstBlank(Excel.Application excel, dynamic sheet)
{
int count = 0;
for (int i = 0; i < sheet.UsedRange.Columns.Count; i++)
{
if (IsBlankCol(excel, sheet, i + 1))
break;
count++;
}
return count;
}
private static bool IsBlankCol(Excel.Application excel, dynamic sheet, int col)
{
for (int i = 0; i < sheet.UsedRange.Rows.Count; i++)
{
if (null != sheet.Cells[i + 1, col].Value)
{
return false;
}
}
return true;
}
private static bool IsBlankRow(Excel.Application excel, dynamic sheet, int row)
{
for (int i = 0; i < sheet.UsedRange.Columns.Count; i++)
{
if (null != sheet.Cells[i + 1, row].Value)
{
return false;
}
}
return true;
}
私有静态字符串[,]LoadCellData(Excel.Application Excel,动态工作表)
{
int countCols=CountColsToFirstBlank(excel,表格);
int countRows=CountRowsToFirstBlank(excel,工作表);
cellData=新字符串[countCols,countRows];
串基准;
for(int i=0;i private static string[,] LoadCellData(Excel.Application excel, dynamic sheet)
{
int countCols = CountColsToFirstBlank(excel, sheet);
int countRows = CountRowsToFirstBlank(excel, sheet);
cellData = new string[countCols, countRows];
string datum;
for (int i = 0; i < countCols; i++)
{
for (int j = 0; j < countRows; j++)
{
try
{
if (null != sheet.Cells[i + 1, j + 1].Value)
{
datum = excel.Cells[i + 1, j + 1].Value.ToString();
cellData[i, j] = datum;
}
}
catch (Exception ex)
{
lastException = ex;
//Console.WriteLine(String.Format("LoadCellData [{1}, {2}] reported an error: [{0}]", ex.Message, i, j));
}
}
}
return cellData;
}
private static int CountRowsToFirstBlank(Excel.Application excel, dynamic sheet)
{
int count = 0;
for (int j = 0; j < sheet.UsedRange.Rows.Count; j++)
{
if (IsBlankRow(excel, sheet, j + 1))
break;
count++;
}
return count;
}
private static int CountColsToFirstBlank(Excel.Application excel, dynamic sheet)
{
int count = 0;
for (int i = 0; i < sheet.UsedRange.Columns.Count; i++)
{
if (IsBlankCol(excel, sheet, i + 1))
break;
count++;
}
return count;
}
private static bool IsBlankCol(Excel.Application excel, dynamic sheet, int col)
{
for (int i = 0; i < sheet.UsedRange.Rows.Count; i++)
{
if (null != sheet.Cells[i + 1, col].Value)
{
return false;
}
}
return true;
}
private static bool IsBlankRow(Excel.Application excel, dynamic sheet, int row)
{
for (int i = 0; i < sheet.UsedRange.Columns.Count; i++)
{
if (null != sheet.Cells[i + 1, row].Value)
{
return false;
}
}
return true;
}
for (int i = 0; i < worksheets.Count; i++)
{
sheet = worksheets[i + 1];
sheet.Columns("A:A").SpecialCells(XlCellType.xlCellTypeBlanks).EntireRow.Delete
sheet.Rows("1:1").SpecialCells(XlCellType.xlCellTypeBlanks).EntireColumn.Delete
Marshal.FinalReleaseComObject(sheet);
}
excel.Worksheet tempSheet = workbook.Worksheets.Add();
tempSheet.Name = sheetName;
workbook.Save();
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();
}
for (int rowIndex = workSheet.Dimension.Start.Row; rowIndex <= workSheet.Dimension.End.Row; rowIndex++)
{
//Assume the first row is the header. Then use the column match ups by name to determine the index.
//This will allow you to have the order of the header.Keys change without any affect.
var row = workSheet.Cells[string.Format("{0}:{0}", rowIndex)];
// check if the row and column cells are empty
bool allEmpty = row.All(c => string.IsNullOrWhiteSpace(c.Text));
if (allEmpty)
continue; // skip this row
else{
//here read header
if()
{
//some code
}
else
{
//some code to read body
}
}
}
var lastcell = sheet.Cells.SpecialCells(XlCellType.xlCellTypeLastCell);
var filledcells = sheet.Cells.Range[sheet.Cells.Item[1, 1],
sheet.Cells[lastcell.Row - 1, lastcell.Column]]
.CurrentRegion;
filledcells.ExportAsFixedFormat(