【问题标题】:Get Excel data range using oledb in c#在c#中使用oledb获取Excel数据范围
【发布时间】:2022-02-16 20:06:30
【问题描述】:

我想通过使用 oledb 来获取 excel 工作表使用的数据范围。 代码如下,

String strExcelConn = "Provider=Microsoft.Jet.OLEDB.4.0;"
                                    + "Data Source=E:\\DOTNET\\CrsMicro\\CA.xls;"
                                    + "Extended Properties='Excel 8.0;HDR=Yes'";


using (OleDbConnection connExcel = new OleDbConnection(strExcelConn))
        {
            string selectString = "SELECT * FROM [CA$A1:D500]";
            using (OleDbCommand cmdExcel = new OleDbCommand(selectString,connExcel))
            {
                cmdExcel.Connection = connExcel;
                connExcel.Open();
                DataTable dt=new DataTable();                    
                OleDbDataAdapter adp = new OleDbDataAdapter();
                adp.SelectCommand = cmdExcel;
                adp.FillSchema(dt, SchemaType.Source);
                adp.Fill(dt);
                int range=dt.Columns.Count;
                int row = dt.Rows.Count;

            //var result = cmdExcel.ExecuteReader();

            //DataTable dtExcelSchema;
            //dtExcelSchema = connExcel.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
           // string excelsheetname = dtExcelSchema.Rows[0].ItemArray[2].ToString();
            connExcel.Close();
            //string sheetName = dtExcelSchema.Rows[0]["TABLE_NAME"].ToString();
        }
    }

我的工作表范围并不总是 A1:D500,它可能经常变化。所以我需要动态获取工作表范围。我知道这可以通过互操作来实现,但我需要在 oledb 中完成。有什么建议吗?

【问题讨论】:

  • 您可以使用 VSTO (Visual Studio Tools for Office) 并在 Excel 中查询选定的范围,或者弹出一个输入框询问用户某个范围。 VSTO 与互操作一起使用
  • 让我理解,如果您知道范围,只需将 A1:D500 动态替换为所需的实际范围即可。上面的代码好像没有错。
  • 我可以看到反对使用 Interop 的原因,但使用 OLEDB 驱动程序有很多陷阱(文件类型,仅适用于统一表,奇怪的行类型猜测)。我建议查看像 OpenXML SDK (用于 xlsx)或类似 github.com/ExcelDataReader/ExcelDataReader 的托管替代方案
  • 如果您只使用工作表名称,后跟“$”,将返回使用的范围,例如,SELECT * FROM [CA$]
  • 是的,我需要知道范围,基于此我需要为其他 puepose 动态生成 sql 查询。 @Doug 是的 select * from [ca$] 将获得使用范围。但是对于少数业务逻辑,我需要根据范围进行操作。

标签: c# excel


【解决方案1】:

创建一个命名范围: https://msdn.microsoft.com/EN-US/library/office/ff196817.aspx 并将selectString替换为

"SELECT * FROM [CA$MyNamedRange]"

【讨论】:

    【解决方案2】:

    您好,我也在 OLEDB C# excel 中解决相同类型的问题,我找到了以下解决方案。这个对我有用。但我是 C# 新手,我不确定它的效率如何。 但到目前为止,它满足了我的要求。这可能对其他人有帮助。

    我能够从浏览的输入 excel 文件中获取 excel 工作表中的动态范围(确保 excel 文件不包含隐藏工作表)。这非常适用于包含单张工作表的 excel 工作簿。我还没有测试过多张纸。

    Range: A [stat value]: Column Name[0] // 返回从起始值到列名的所有行。 示例:A1:M0 //它将返回从 A1 到 M 列的所有行。所以这里不必担心你的 excel 中有多少行。 只需给出 Column Name[0] 即可获取从开始到列 M 的所有行。 所以 '0' 将是我们的外部范围。

    //Code under actual c# clas file where we are uploading excel.
    Excel_Common excelComm = new Excel_Common(); // object to Excel_Common class file
    
    string rangeStringwithSHeet =excelComm.GetSheetName(filepath).ToString().Trim('\'') + GetRange(excelComm.GetSheetName(filepath), excelComm.ExcelConn(filepath));
    
    queryForExcelInput = string.Format("SELECT * FROM [{0}]", rangeStringwithSHeet);
    
    Econ1 = new OleDbConnection(excelComm.ExcelConn(filepath));
    Econ1.Open();
    dataExcelInputTable = new DataTable();
    OleDbCommand oleDbCommand1 = new OleDbCommand(queryForExcelInput, Econ1);
    OleDbDataAdapter oleDbDaAdapter1 = new OleDbDataAdapter(oleDbCommand1);
    oleDbDaAdapter1.Fill(dataExcelInputTable);
    

    Excel_Common 类文件有以下方法:

    //Get Range like A4:M30
    
        public string GetRange(string SheetName, string excelConnectionString)
       {
            string rangeInput = "",rangeColName="";
            int columnsCount = 0;
            int rowStartRange = 0;
    
            columnsCount = GetNumberOfColumnsInSheet(SheetName, excelConnectionString);
            rowStartRange = GetStartRowRange(SheetName, excelConnectionString); // This is optional if you want always A1. just assign 1 here 
            while (columnsCount > 0)
            {
                columnsCount--;
                rangeColName = (char)('A' + columnsCount % 26) + rangeColName;
                columnsCount /= 26;
            }
    
            rangeInput = "A" + rowStartRange + ":" + rangeColName + "0";
    
    
    
            return rangeInput;
        }
    
    
    
    // Get Sheet Name assuming only one sheet for workbook and no hidden sheets
     public string GetSheetName(string filepath)
     {
     string sheetname = "";
     String connect = ExcelConn(filepath);
     OleDbConnection con = new OleDbConnection(connect);
     con.Open();
    
     DataTable tables = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
    
            foreach (DataRow row in tables.Rows)
            {
                sheetname = row[2].ToString();
                if (!sheetname.EndsWith("$"))
                    continue;
    
            }
    
      con.Close();
      return sheetname;
     }
    
    
    // Get number of columns in a given sheet
        public int GetNumberOfColumnsInSheet(string SheetName, string excelConnectionString)
        {
            int columnsCount = 0;
    
            //If a valid excel file
            if (!string.IsNullOrEmpty(excelConnectionString))
            {
                using (OleDbConnection conn = new OleDbConnection(excelConnectionString))
                {
                    conn.Open();
                    DataTable dt = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, null);
                    if (dt.Rows.Count > 0)
                    columnsCount = dt.AsEnumerable().Where(a => a["TABLE_NAME"].ToString() == SheetName).Count();
                    conn.Close();
                }
            }
            return columnsCount;
        }
    
    
    // Get the first row count in sheet contains some keyword . This method call is optional if you always want A1. Here I need to check some keyword exist and from there only I have to start something like A4
    
    
    public int GetStartRowRange(string SheetName, string excelConnectionString)
     {
         int rowStartRange = 1;
    
         //If a valid excel file
         if (!string.IsNullOrEmpty(excelConnectionString))
         {
             using (OleDbConnection conn = new OleDbConnection(excelConnectionString))
             {
                 string colValue;
                 conn.Open();
                 string cmdstr = "select * from [" + SheetName + "]";
    
                 OleDbCommand com = new OleDbCommand(cmdstr, conn);
                 DataTable dt = new DataTable();
                 OleDbDataAdapter da = new OleDbDataAdapter(com);
                 da.Fill(dt);
    
    
    
                 // get first row data where it started
    
                 foreach (DataRow dataRow in dt.Rows)
                 {
    
                     colValue = dataRow[0].ToString();
    
    
                     if ((colValue.Contains("Value1") || colValue.Contains("Value2") || colValue.Contains("Value3")) && (string.IsNullOrEmpty(dataRow[1].ToString()) == false))
                     {
                         rowStartRange = rowStartRange + 1;
                         break;
                     }
                     else
                     {
                         rowStartRange = rowStartRange + 1;
                     }
    
                 }
    
                 conn.Close();
    
    
             }
    
         }
         return rowStartRange;
     }
    
    
    // Connection to excel document
    public string ExcelConn(string FilePath)
    {
        string constr = "";
        string extension = Path.GetExtension(FilePath);
    
        //Checking for the extentions, if XLS connect using Jet OleDB
        if (extension.Equals(".xls", StringComparison.CurrentCultureIgnoreCase))
        {
            constr = string.Format("Provider=Microsoft.Jet.OLEDB.4.0; Data Source={0};Extended Properties=\"Excel 12.0;IMEX=1;HDR=YES\"", FilePath);
        }
        //Use ACE OleDb if xlsx extention
        else if (extension.Equals(".xlsx", StringComparison.CurrentCultureIgnoreCase))
        {
            constr = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 8.0;IMEX=1;HDR=YES\"", FilePath);
        }
    
    
        return constr;
    
    } // end of ExcelConn method
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-06
      • 2016-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-18
      • 1970-01-01
      • 2013-06-11
      相关资源
      最近更新 更多