Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Excel互操作删除空行_C#_Office Interop_Excel Interop - Fatal编程技术网

C# 使用Excel互操作删除空行

C# 使用Excel互操作删除空行,c#,office-interop,excel-interop,C#,Office Interop,Excel Interop,我有用户提供的excel文件,需要转换为PDF。使用excel interop,我可以使用.ExportAsFixedFormat()完成这项工作。当工作簿有数百万行时,我的问题就出现了。这将变成一个具有50k+页的文件。如果工作簿中所有这些行都有内容,那就好了。但是,每次出现其中一个文件时,可能会有50行包含内容,其余的都是空白。如何删除空行,以便将其导出为大小合适的PDF 我试着从最后一行开始,一个接一个地使用CountA检查该行是否有内容,如果有,则将其删除。这不仅要花费很长时间,而且在大

我有用户提供的excel文件,需要转换为PDF。使用excel interop,我可以使用
.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页)
  • 使用“特殊粘贴”,以便保留格式设置
  • 尝试分析sheet2中未使用的行

  • 如果这没有帮助,请尝试在清除格式信息的情况下重复步骤2,然后解析sheet2。您可以随时稍后复制格式信息(如果格式信息足够简单)

    如果您可以首先通过OleDBAdapter将Excel文件加载到数据集中,则在导入时删除空白行相对容易。。。 试试我通过堆栈溢出发布的这个


    然后将数据集导出到新的Excel文件,并将该文件转换为PDF。这可能是一个很大的“如果”,当然这取决于excel的布局(或者缺少)

    我今天必须解决这个问题,因为这可能是您可能的案例的一个子集

    如果电子表格满足以下条件:

  • 所有包含数据的列在第1行中都有标题文本
  • 在第一个空白行之前,所有包含数据的行都是按顺序排列的
  • 然后,以下代码可能会有所帮助:

        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(