c# - 使用互操作和 C# 计算 Excel 电子表格工作表中的行数,其中数据为

标签 c# excel com-interop

我刚刚编写了一些被认为是完全丑陋的代码,用于计算给定目录中所有电子表格中名为“数据”的工作表中包含数据的行数。这是代码

    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);
            }
        }

我不敢相信这是正确的方法。它非常慢,并且包括对名称如 Value2 的属性的调用,这些名称不像公共(public) API 的预期部分。但方法suggested elsewhere大大超出了报告的行数(其中包含数据)。

正确的做法是计算 Excel 工作表中包含数据的行数?

==========编辑1==========

UsedRange.Rows.CountSid's ACE.OLEDB solution 的原因在报告中,行数似乎是应用于某些列的粉红色背景颜色(但仅扩展到第 7091 行)。是否有一种简单/优雅的方法来计算其中包含数据的行(即非空单元格值),而不管显示颜色如何?

==========编辑2===========

Sid's ACE.OLEDB solutionthe addition he suggests这样 tSQL 行就会读取

var sql = "SELECT COUNT (*) FROM [" + sheetName + "$] WHERE NOT F1 IS NULL";

有效。我会将其标记为答案。

最佳答案

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

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;
}

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

关于c# - 使用互操作和 C# 计算 Excel 电子表格工作表中的行数,其中数据为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13534241/

相关文章:

c# - 将矩形图像拆分为多边形以模拟 splinter 玻璃

c# - 是否可以在对 Where 的调用中调用命名方法?

c# - 如何将链接参数添加到 ASP.NET Core MVC 中的 asp 标记助手

vba - 根据列和行总计计算值矩阵

c++ - COM 代码库位置 - 如何选择要使用的版本?

multithreading - 将托管 .NET 客户端设置为使用 STA 线程是否有任何原因会导致 native COM 服务器中出现异常问题?

c# - 如何延迟发送电子邮件?

excel - 使用 Excel 模块通过 write_formula() 将单元格值读取为字符串集

excel - .Add2 生成运行时错误 '438' : Object doesn't support this property or method in Excel VBA

c# - 释放 Excel COM 对象