C# 使用interop和c来计算Excel电子表格工作表中包含数据的行数

C# 使用interop和c来计算Excel电子表格工作表中包含数据的行数,c#,excel,com-interop,C#,Excel,Com Interop,我刚刚编写了一段被认为是非常可怕的代码,用来计算工作表中包含数据的行数,该工作表称为给定目录中所有电子表格中的数据。这是密码 private const string _ExcelLogDirectoryPath = @"..\..\..\..\Model\ExcelLogs\"; static void Main() { var excelLogPaths = Directory.GetFiles(_ExcelLogDirectoryPath, "*.x

我刚刚编写了一段被认为是非常可怕的代码,用来计算工作表中包含数据的行数,该工作表称为给定目录中所有电子表格中的数据。这是密码

    private const string _ExcelLogDirectoryPath = @"..\..\..\..\Model\ExcelLogs\";
    static void Main()
    {
        var excelLogPaths = Directory.GetFiles(_ExcelLogDirectoryPath, "*.xl*");
        var excel = new Microsoft.Office.Interop.Excel.Application();
        var excelRowCounts = new Dictionary<string, int>();
        foreach (var filePath in excelLogPaths)
        {
            var spreadsheet = excel.Workbooks.Open(Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + "/" + filePath);
            var worksheet = spreadsheet.Sheets["Data"] as Worksheet;
            if (worksheet != null)
            {
                // var rowCount = UsedRange.Rows.Count - 1; DOES NOT WORK, THE number is bigger than the 'real' answer
                var rowCount = 0;
                for (var i = 1 ; i < 1000000000; i++)
                {
                    var cell = worksheet.Cells[i, 1].Value2; // "Value2", great name for a property, thanks guys
                    if (cell != null && cell.ToString() != "") // Very fragile (e.g. skipped rows will break this)
                    {
                        rowCount++;
                    }
                    else
                    {
                        break;
                    }
                }
                var name = spreadsheet.Name.Substring(spreadsheet.Name.IndexOf('p'), spreadsheet.Name.IndexOf('.') - spreadsheet.Name.IndexOf('p'));
                excelRowCounts.Add(name, rowCount - 1);
            }
        }

工作。我将把它标记为答案。

这应该可以解决问题。您可以使用每个文件名调用它来检索行数

private string GetNumberOfRows(string filename, string sheetName)
{
    string connectionString;
    string count = "";

    if (filename.EndsWith(".xlsx"))
    {
        connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filename + ";Mode=ReadWrite;Extended Properties=\"Excel 12.0;HDR=NO\"";
    }
    else if (filename.EndsWith(".xls"))
    {
        connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filename + ";Mode=ReadWrite;Extended Properties=\"Excel 8.0;HDR=NO;\"";
    }

    string SQL = "SELECT COUNT (*) FROM [" + sheetName + "$]";

    using (OleDbConnection conn = new OleDbConnection(connectionString))
    {
        conn.Open();

        using (OleDbCommand cmd = new OleDbCommand(SQL, conn))
        {
            using (OleDbDataReader reader = cmd.ExecuteReader())
            {
                reader.Read();
                count = reader[0].ToString();
            }
        }

        conn.Close();
    }

    return count;
}

可能有一种更快速的方法只检索行数,但我知道这是可行的。

如果使用interop,为什么不使用UsedRange

_Worksheet.UsedRange.Rows.Count

OleDb是您的选择吗?如果您只想计算已使用的行数,而不关心格式,那么这比互操作快得多。查找已使用行数是您需要的最重要的代码块吗?如果是这样,您可以使用高性能excel函数,并使用interop将其插入c。一些感谢Sid-您是否有一个指针,指示如何使用OleDb计算Excel工作表中已使用的行数?快点就好了!谢谢,这篇文章是关于VBA的,我想我的部分问题是解决Excel中VBA和外部C Interop之间的转换。例如,这篇文章推荐Cells.FindWhat:=*,After:=[A1],SearchOrder:=xlByRows,SearchDirection:=xlPrevious.Row,但我不知道如何在C interopt中使用它。这很旧,但我相信它应该是worker.Cells.Find*,After:Worksheet.GetRange1,1,SearchOrder:Microsoft.Office.Interop.Excel.XlSearchOrder.xlByRows,SearchDirection:Microsoft.Office.Interop.Excel.XlSearchDirection.xlPrevious.Row;和this.worksheet.Cells.Find*,后面是:this.worksheet.GetRange1,1,SearchOrder:Microsoft.Office.Interop.Excel.XlSearchOrder.xlByColumns,SearchDirection:Microsoft.Office.Interop.Excel.XlSearchDirection.xlPrevious.Column为最后使用的列。如果它是xlsm文件,我是否将其与xlsx相同?hmm…不确定。我会根据创建它的Excel版本来处理它。对于2003年和更早的版本,将其视为.xls;对于2007年和以后的版本,将其视为.xlsx。我没有尝试启用宏的工作簿,因此您可能需要对其进行测试。我有一个Microsoft.ACE.OLEDB.12.0提供程序未在本地计算机上注册错误。我使用Office 2013使用Win 8,并按照中的说明从@dumbledad Interest下载。您确定这些单元格没有任何其他可能导致其显示为正在使用的单元格吗?看起来很奇怪,你尝试过的每件事都会重复计算到完全相同的数字。@dumbledad有趣的是,我没有意识到OleDb包含没有文本的行。乍一看,有一种解决方法:在SQL中,您可以包含一个带有excludes NULL的条件,但您需要对每一列执行此操作:从[Sheet1$]中选择COUNT*,其中F1不为NULL,F2为NULL,F3为NULL。。。如果您没有标题,或者如果有,请命名标题。我在问题中提到了这一点,它是在代码列表中注释掉的一行。我发现UsedRange.Rows.Count过度报告了中包含数据的行数。不知道为什么,也许是旧格式?不过我想这应该会让你耳目一新
_Worksheet.UsedRange.Rows.Count