2

So far I have managed to get the column names of the whole excel file, but what I would like to do is to get the column names of the excel file of a given table (sheet). How could I modify the code to achieve this. I have been trying for a while now with no positive results, any help much appreciated.

public static List<String> ReadSpecificTableColumns(string filePath, string sheetName)
    {
        var columnList = new List<string>();
        try
        {
            var excelConnection = new OleDbConnection("provider=Microsoft.ACE.OLEDB.12.0;Data Source='" + filePath + "';Extended Properties='Excel 12.0;IMEX=1'");
            excelConnection.Open();
            var columns = excelConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, null);
            excelConnection.Close();

            if (columns != null)
            {
                columnList.AddRange(from DataRow column in columns.Rows select column["Column_name"].ToString());
            }

        }
        catch (Exception exception)
        {
            Console.WriteLine(exception.Message);
        }

        return columnList;
    }

5 Answers 5

3

You did not include sheet name in your code.
You can try below code:

var adapter = new OleDbDataAdapter("SELECT * FROM [" +sheetName + "$]", excelConnection);
var ds = new DataSet();
adapter.Fill(ds, "myTable");
DataTable data = ds.Tables["myTable"];

foreach(DataColumn  dc in data.Columns){
...
}
Sign up to request clarification or add additional context in comments.

4 Comments

I have been using similar code to yours (which I have not posted here), but in this way the code reads all the rows of the specified sheet and would like to avoid that. The ideas is having a file with i.e 5 sheets to get 5 sets of column names without reading all the data, then when i find a keyword in one of the sets I read the contents of the sheet where the keyword was found.
You ar right but I googled your approach but did not find any similar result
Yes, I have been looking for a while now. Maybe is not applicable. Thanks for your time and effort :)
You are welcome, I am curios about solution if you find then you can share here.
2

What about using such snippet:

var adapter = new OleDbDataAdapter("SELECT * FROM [" +sheetName + "$A1:Z1]", excelConnection);
var table = new DataTable();
adapter.Fill(table);

For connection string with "HDR=Yes" it will read first row and the destination table will have all columns but no data.

Comments

0

You can do something like this:

    private void ValidateExcelColumns(string filePath)
    {            
        var connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filePath + ";Extended Properties=\"Excel 12.0;IMEX=1;HDR=Yes;TypeGuessRows=0;ImportMixedTypes=Text\""; ;
        using (var conn = new OleDbConnection(connectionString))
        {
            conn.Open();

            DataTable dt = new DataTable();
            var sheets = conn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
            using (var cmd = conn.CreateCommand())
            {
                cmd.CommandText = "SELECT TOP 1 * FROM [" + sheets.Rows[0]["TABLE_NAME"].ToString() + "] ";
                var adapter = new OleDbDataAdapter(cmd);
                adapter.Fill(dt);
            }

            foreach(DataColumn column in dt.Columns)
            {
                //Do something with your columns
            }
        }
    }

Comments

0

I had to go dig this up since it was not in the first click in search engine.

It is much better to go to the schema tables of the OleDb since it defines the schema the provider gave for the OleDb connection. Most are querying the Table and getting the schema information from there, and if the table is very large the query could take more time. Time might be irrelevant since we are talking about excel tables and most excel table sizes are small.

The Original poster was mostly there, they just needed a select statement on their schema columns table to select the schema data for their table:
DataRow[] shtRows = schemaDT.Select("[TABLE_NAME] = 'Sheet1$'");

This solution is provider independent and there is no need to guess or know how the schema of your dataset is created.

The OleDb contains tables that outline the schema definition of the importing data. Since the provider does a bunch of items behind the scenes (i.e. Auto forces data type to number even if you specify force to text [IMEX=1] due to it taking a sample of first few entries).

The schema tables can be retrieved by the GetOleDbSchemaTable() function. Below the [XXX] can be replace with any item from the OleDbSchemaGuid class. To answer the question here Columns was used:

    DataTable schemaDT = oleConn.GetOleDbSchemaTable(OleDbSchemaGuid.[XXX], null);

Columns -- Returns the columns of tables (including views) defined in the catalog that is accessible to a given user.

This can pull out the column names:

    using System;
    using System.Linq;
    using System.Data;
    using System.Data.OleDb;
    using System.Collections.Generic;

    namespace ConsoleApp1
    {
        class Program
        {
            static void Main(string[] args)
            {
                string excelFilePath = @"C:\myexcelfile.xlsx";
                string providerString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0 Xml; HDR=YES;IMEX=1\";";
               
                List<string> columnNames = new List<string>();
                using (OleDbConnection oleConn = new OleDbConnection(String.Format(providerString, excelFilePath)))
                {
                    oleConn.Open();
                    DataTable schemaDT = oleConn.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, null);
                    DataRow[] shtRows = schemaDT.Select("[TABLE_NAME] = 'Sheet1$'");
                    columnNames = shtRows.Select(o => o.Field<string>("COLUMN_NAME")).ToList();
                }

                Console.WriteLine(String.Join("\n", columnNames));
                Console.ReadLine();
            }
        }
    }

1 Comment

Remember that Stack Overflow isn't just intended to solve the immediate problem, but also to help future readers find solutions to similar problems, which requires understanding the underlying code. This is especially important for members of our community who are beginners, and not familiar with the syntax. Given that, can you edit your answer to include an explanation of what you're doing and why you believe it is the best approach?
0

This function easily returns the columns of your sheet using OleDbConnection:

Public Function GetColumnNames(Optional SheetName As String = Nothing) As DataTable
    Try
        Dim dt As New DataTable
        
        Using OleCon = New OleDbConnection(ConnectionString)
        
            OleCon.Open()

            dt = OleCon.GetOleDbSchemaTable(OleDbSchemaGuid.Columns,
                    New String() {Nothing, Nothing, SheetName})

            OleCon.Close()
        
        End Using
        
        Return dt
        
    Catch ex As Exception
        Return Nothing
    End Try
End Function

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.