In C#, how do I get the column name from a worksheet in an Excel file?
Here is my code so far:
ConnectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0 Xml;HDR=YES;IMEX=1\";", "#"C:\file.xlsx");
objConn.Open();
OleDbCommand objCmdSelect = new OleDbCommand("SELECT * FROM ["xlWorksheet"$]", objConn);
OleDbDataAdapter objAdapter1 = new OleDbDataAdapter();
objAdapter1.SelectCommand = objCmdSelect;
DataSet objDataset1 = new DataSet();
objAdapter1.Fill(objDataset1);
objConn.Close();
Does you connection string include the HDR=YES ?:
Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\myFolder\myExcel2007file.xlsx;Extended Properties="Excel 12.0 Xml;HDR=YES";
Once you populate your DataTable or DataSet you can treat the usual way:
dt.Columns[0].ColumnName
Or:
// For each DataTable, print the ColumnName.
foreach(DataTable table in dataSet.Tables)
{
foreach(DataColumn column in table.Columns)
{
Console.WriteLine(column.ColumnName);
}
}
Also this does not look syntax correct:
OleDbCommand objCmdSelect = new OleDbCommand("SELECT * FROM ["xlWorksheet"$]", objConn);
Should be something like:
OleDbCommand objCmdSelect = new OleDbCommand("SELECT * FROM [" + xlWorksheet + "$]", objConn);
Finally, if you time - investigate EPPlus (open source) for reading/writing Excel - http://epplus.codeplex.com as it works in both 32-bit and 64-bit environments.
Related
I have run into a snag when reading info from a workbook in excel that contains a "#" in the name of the sheet. I am able to select the WHOLE worksheet but not a range in the worksheet.
Code:
using (OleDbConnection conn = new OleDbConnection())
{
DataTable dt = new DataTable();
string Import_FileName = "C:/TestExcel/TestWorkbook.xlsm";
conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + Import_FileName + ";" + "Extended Properties='Excel 12.0 Xml;HDR=YES;'";
using (OleDbCommand comm = new OleDbCommand())
{
comm.CommandText = "Select * from [Sheet #1$A1:A22]";
comm.Connection = conn;
using (OleDbDataAdapter da = new OleDbDataAdapter())
{
da.SelectCommand = comm;
da.Fill(dt);
}
}
}
And the following queries work just fine.
comm.CommandText = "Select * from [Sheet #1$]";
comm.CommandText = "Select * from [Sheet2$A1:A22]";
I get the following exception saying it cannot find the table in question.
The Microsoft Office Access database engine could not find the object 'Sheet .1$A1:A22'.
Here is my code:
public static DataTable GetDataFromSpreadsheet(OleDbConnection conn)
{
DataTable dt = new DataTable();
OleDbCommand cmd = new OleDbCommand("SELECT * FROM [Sheet1$]", conn);
conn.Open();
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
da.Fill(dt);
conn.Close();
return dt;
}
When this method is called, I don't get an error at all! When I put a watch on the data table (dt), I can see that it is empty. No row headers, and the rows are empty. I know the query is valid to some degree, because the Rows.Count on dt returns the number of rows in the sheet that I am querying.
What could I be doing incorrectly?
Thanks for the help!
EDIT: Here is my Connection String
<add name="EXCEL" connectionString="Provider=Microsoft.ACE.OLEDB.12.0;
Data Source={0};
Extended Properties='Excel 8.0;
HDR=Yes; IMEX=1;'" />
I am putting the file location in place of {0}
Establish a Connection
String strExcelConn = "Provider=Microsoft.Jet.OLEDB.4.0;"
+ "Data Source=Book1.xls;"
+ "Extended Properties='Excel 8.0;HDR=Yes'";
OleDbConnection connExcel = new OleDbConnection(strExcelConn);
OleDbCommand cmdExcel = new OleDbCommand();
cmdExcel.Connection = connExcel;
Accessing Sheets
connExcel.Open();
DataTable dtExcelSchema;
dtExcelSchema = connExcel.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
connExcel.Close();
DataSet ds = new DataSet();
string SheetName = dtExcelSchema.Rows[0]["TABLE_NAME"].ToString();
cmdExcel.CommandText = "SELECT * From [" + SheetName + "]";
da.SelectCommand = cmdExcel;
da.Fill(ds);
connExcel.Close();
REFERENCE.
Follow this link
https://www.connectionstrings.com/excel/
Try setting IMEX=1 or HDR=YES in your connection string
DataAdapter.Fill Method overload list is following:
Fill(DataSet)
Fill(DataTable, IDataReader)
Fill(DataTable[], IDataReader, Int32, Int32)
Fill(DataSet, String, IDataReader, Int32, Int32)
There is no method with single DataTable parameter.
In your case you can use Fill(DataSet) method and return .Tables[0] or .Tables["TableName"];
Have a look following code:
public static DataTable GetDataFromSpreadsheet(OleDbConnection conn)
{
DataSet ds = new DataSet();
OleDbCommand cmd = new OleDbCommand("SELECT * FROM [Sheet1$]", conn);
conn.Open();
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
da.Fill(ds);
conn.Close();
return ds.Tables[0];
}
I am using OLEDB to read the data from an Excel spreadsheet.
var connectionString =
string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0}; Extended Properties=Excel 12.0;", fileName);
var adapter = new OleDbDataAdapter("SELECT * FROM [sheet1$]", connectionString);
var ds = new DataSet();
adapter.Fill(ds, "mySheet");
var data = ds.Tables["mySheet"].AsEnumerable();
foreach (var dataRow in data)
{
Console.WriteLine(dataRow[0].ToString());
}
Instead of passing an index to the DataRow to get the value of a column, is there anyway to retrieve the column by the name of the column header?
Try this code:
var connectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0}; Extended Properties=Excel 12.0; HDR=YES", fileName);
var adapter = new OleDbDataAdapter("SELECT * FROM [sheet1$]", connectionString);
var ds = new DataSet();
adapter.Fill(ds, "mySheet");
var data = ds.Tables["mySheet"].AsEnumerable();
foreach (DataRow dataRow in data)
{
Console.WriteLine(dataRow["MyColumnName"].ToString());
Console.WriteLine(dataRow.Field<string>("MyColumnName").ToString());
}
I added in 2 ways to access the data in the row via column Name.
Hope this does the trick!!
Modify your connection string to specify that you have headers in your excel file.
You can do this by setting the HDR value.
Refer this link to for various variations of connection string and build the one that suits your needs"
http://www.connectionstrings.com/excel/
Use a DataTable to have your data.
string strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + **EXCEL FILE PATH** + ";Extended Properties=\"Excel 8.0;HDR=YES;IMEX=1\"";
OleDbConnection conn = new OleDbConnection(strConn);
conn.Open();
OleDbCommand cmd2 = new OleDbCommand("SELECT * FROM [**YOUR SHEET** $]", conn);
cmd2.CommandType = CommandType.Text;
DataTable outputTable2 = new DataTable("myDataTable");
new OleDbDataAdapter(cmd2).Fill(outputTable2);
foreach(Datarow row in outputTable2)
{
String s = row["yourcolumnheader"].ToString();
}
I have excel file with 2 tables. I need to read this tables and get all the values from this tables. But all for what I have is:
OleDbConnection cnn = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\MigrateExelSql\Include\TestDb.xlsx; Extended Properties=Excel 12.0;");
OleDbCommand oconn = new OleDbCommand("select * from [Sheet1$]", cnn);
cnn.Open();
OleDbDataAdapter adp = new OleDbDataAdapter(oconn);
DataTable dt = new DataTable();
adp.Fill(dt);
And I don't uderstand what I need to write for get the all values from Username and Email tables. Here is the .xlsx table TestDb Please can somebody help me, because I'm googling the second day and I have no idea for what I must to do.
And when I try to get values by this method it return me an error:
var fileName = string.Format("{0}\\Include\\TestDb.xlsx", Directory.GetCurrentDirectory());
var connectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0}; Extended Properties=Excel 12.0;", fileName);
var adapter = new OleDbDataAdapter("SELECT * FROM [Sheet1$]", connectionString);
var ds = new DataSet();
adapter.Fill(ds, "Username");
var data = ds.Tables["Username"].AsEnumerable();
foreach (var item in data)
{
Console.WriteLine(item);
}
Console.ReadKey();
One more Edit:
string con =
#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\MigrateExelSql\Include\TestDb.xlsx; Extended Properties=Excel 12.0;";
using(OleDbConnection connection = new OleDbConnection(con))
{
connection.Open();
OleDbCommand command = new OleDbCommand("select * from [Sheet1$]", connection);
using(OleDbDataReader dr = command.ExecuteReader())
{
while(dr.Read())
{
var row1Col0 = dr[0];
Console.WriteLine(row1Col0);
}
}
}
Console.ReadKey();
This will read only first column, but when I try to read dr[1] it will return error: Index was outside bound of the array.
Your xlsx file contains only one sheet and in that sheet there is only one column.
A sheet is treated by the OleDb driver like a datatable and each column in a sheet is considered a datacolumn.
You can't read anything apart one table (Sheet1$) and one column (dr[0]).
If you try to read dr[1] then you are referencing the second column and that column doesn't exist in Sheet1.
Just to test, try to add some values in the second column of the Excel file.
Now you can reference dr[1].
I want to read Excel file in c# using following code
string excelFileName = "Book2.xls";
string excelConnectString = #"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=Book2.xls;Extended Properties=""Excel 8.0;HDR=YES;""";
//string excelConnectString = #"Provider = Microsoft.Jet.OLEDB.4.0;Data Source = " + excelFileName + ";" + "Extended Properties = Excel 8.0; HDR=Yes;IMEX=1";
OleDbConnection objConn = new OleDbConnection(excelConnectString);
OleDbCommand objCmd = new OleDbCommand("Select * From [Sheet1$]", objConn);
OleDbDataAdapter objDatAdap = new OleDbDataAdapter();
objDatAdap.SelectCommand = objCmd;
DataSet ds = new DataSet();
objDatAdap.Fill(ds);
Everything is working fine.Now my requirement is to read the excel file something like below
SELECT A,B,D From [Sheet1];
The Select-command should look like this if you want to read A1 to D1:
SELECT * FROM [SHEETNAME_HERE$A1:D1]
Whole Code:
OleDbConnection con = new OleDbConnection(
"provider=Microsoft.Jet.OLEDB.4.0;data source="
+ XLS_FILE_NAME_AND_PATH_HERE
+ ";Extended Properties=Excel 8.0;");
StringBuilder stbQuery = new StringBuilder();
stbQuery.Append("SELECT * FROM [" + SHEETNAME_HERE + "$A1:D1]");
OleDbDataAdapter adp = new OleDbDataAdapter(stbQuery.ToString(), con);
DataSet dsXLS = new DataSet();
adp.Fill(dsXLS);
DataView dvEmp = new DataView(dsXLS.Tables[0]);
dataGridView1.DataSource = dvEmp;
DataTable Contents = new DataTable();
using (OleDbDataAdapter adapter = new OleDbDataAdapter("Select * From [Sheet1$]", objConn))
{
adapter.Fill(Contents);
}
Console.WriteLine(Contents.Rows[0][0]);
You can select a particular cell by passing the proper index.
You can just constuct use query like that:
SELECT FirstName, LastName, Mobile FROM [Sheet1$]
i.e. use first row values as column names.