This is my first attempt to read an Excel 2007 file via ADO.net, and I must be missing something b/c when I try to run the query, I get an exception. When I started looking, it's b/c the table (worksheet) isn't there. Can someone please tell me what I'm doing wrong?
Here is my code:
string cs = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=My File.xlsx;Extended Properties=""Excel 12.0;IMEX=1;""";
using (OleDbConnection con = new OleDbConnection(cs))
{
con.Open();
string query = "SELECT * FROM [Sheet1$]";
OleDbCommand cmd = new OleDbCommand(query, con);
OleDbDataAdapter adapter = new OleDbDataAdapter(cmd);
DataTable dt = new DataTable();
DataTable worksheets = con.GetSchema("Tables");
adapter.Fill(dt);
.
.
.
}
Take a look at the accepted answer here
The First Column of the excel file to put in string variable C#?
It works for Excel 2003 but I think it could easily be adapted to work with 2007.
Related
I'm trying to figure out why the behavior I'm seeing and the "documented" behavior are different. I've read both of these articles:Read and Write Excel Documents Using OLEDB and Working with MS Excel(xls / xlsx) Using MDAC and Oledb and this is text from the second link.
If you read in the second link it says:
To Retrieve Schema Information of Excel Workbook :
You can get the worksheets that are present in the excel workbook using GetOleDbSchemaTable. Use the following snippet.
DataTable dtSchema = null;
dtSchema = conObj.GetOleDbSchemaTable(
OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
Here dtSchema will hold the list of all workbooks. Say we have two workbooks : wb1, wb2. The above code will return a list of wb1, wb1$,wb2,wb2$. We need to filter out $ elements.
However when I run this code I only get "wb1$ and wb2$". I can easily remove the $ in code but I'm trying to make sure I'm not going to have code that breaks when I put it on a different computers/OS/environment and it behaves as is documented. Can somebody tell my what or if something changed since these were written or if I'm missing some key piece. Something to note this is being developed in VS2015, Windows 7 Pro, and Office 2010 installed.
//Connection String
//string connstring = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties='Excel 8.0;HDR=NO;IMEX=1';"; // Extra blank space cannot appear in Office 2007 and the last version. And we need to pay attention on semicolon.
//string connstring = Provider = Microsoft.JET.OLEDB.4.0; Data Source = " + path + "; Extended Properties = 'Excel 8.0;HDR=NO;IMEX=1'; "; //This connection string is appropriate for Office 2007 and the older version. We can select the most suitable connection string according to Office version or our program.
using (OleDbConnection conn = new OleDbConnection(_connectionString))
{
conn.Open();
//DataTable sheetNames = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" }); //Get All Sheets Name
DataTable sheetNames = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null); //Get All Sheets Name
// Loop through all Sheets to get data
foreach (DataRow dr in sheetNames.Rows)
{
string sheetName = dr["TABLE_NAME"].ToString();
//if (!sheetName.EndsWith("$"))
// continue;
Debug.Print(sheetName);
}
return sheetNames;
Thanks
dbl
I'm using an OleDbConnection to create an Excel file:
String bewegungenDateiname = System.IO.Path.ChangeExtension(System.IO.Path.GetTempFileName(), ".xls");
string strConnectionString = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source="
+ System.IO.Path.GetDirectoryName(bewegungenDateiname) + #"\" + System.IO.Path.GetFileName(bewegungenDateiname)
+ #";Extended Properties='Excel 8.0;HDR=YES'";
using (System.Data.OleDb.OleDbConnection objConn = new System.Data.OleDb.OleDbConnection(strConnectionString))
using (System.Data.OleDb.OleDbCommand cmd = new System.Data.OleDb.OleDbCommand("", objConn))
{
objConn.Open();
cmd.CommandText = "CREATE TABLE [Test] ([MyDecimal] DECIMAL NULL)";
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
Decimal value = 12.34m;
cmd.Parameters.AddWithValue("#P01", value);
cmd.CommandText = "INSERT INTO [Test$] ([MyDecimal]) VALUES (#P01)";
cmd.ExecuteNonQuery();
}
System.Diagnostics.Process.Start(bewegungenDateiname);
Now when Excel 2013 opens the Excel file it will Show:
MyDecimal
1234
So in my case Excel is losing the dot. Now I'm running a german Version of Windows/Office and if I use the following line to add the Parameter it will work:
cmd.Parameters.AddWithValue("#P01", value.ToString());
German localization of numbers uses a colon instead of the dot to separate the fractions from the number value (meaning 12,34 instead of 12.34). So it seems the OleDbConnection uses the wrong culture variant to write the Excel file?
I fear my Version might break with a different Version of Excel or a different locale - is there a way to fix this and get decimal values to Excel without such risks?
I would use some other way to create Excel files, if it is without this flaw.
With Excel 2013 try using the following:
strConnectionString = String.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=""Excel 12.0;HDR=No;IMEX=1""", _filePath)
I have no idea if it will solve the problem.
Thanks Astander for replying to my query
I am here with more detailed query.
string cs = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + #"D:\\sample.xls;" + "Excel 12.0;HDR=YES;";
OleDbConnection Excelcon = new OleDbConnection(cs);
OleDbDataAdapter ad = new OleDbDataAdapter();
ad.SelectCommand = new OleDbCommand("SELECT *FROM [Sheet1$]", Excelcon);
DataTable dt = new DataTable();
ad.Fill(dt);
return dt;
I am getting error at the select statement that :
The Microsoft Office Access database engine could not find the object 'Sheet1$'. Make sure the object exists and that you spell its name and the path name correctly.
Hope someone can help me find a solution.
What worked for me is,
when file was created, it was stored in some specific location. In my case,C:/Documents.
I had manually changed the location to D:
this was what I had written
string connStringExcel = #"Provider=Microsoft.ACE.OLEDB.12.0; Data Source=D:\example.xls;Extended Properties=""Excel 12.0;HDR=YES;""";`
So,the actual path should be
string connStringExcel = #"Provider=Microsoft.ACE.OLEDB.12.0; Data Source=C:\A\Documents\example.xls;Extended Properties=""Excel 12.0;HDR=YES;""";`
So on giving the path of correct location,my query was solved.
Hope it helps someone else too.
// Create connection string variable. Modify the "Data Source"
// parameter as appropriate for your environment.
String sConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data Source=" + Server.MapPath("../ExcelData.xls") + ";" +
"Extended Properties=Excel 8.0;";
// Create connection object by using the preceding connection string.
OleDbConnection objConn = new OleDbConnection(sConnectionString);
// Open connection with the database.
objConn.Open();
// The code to follow uses a SQL SELECT command to display the data from the worksheet.
// Create new OleDbCommand to return data from worksheet.
OleDbCommand objCmdSelect =new OleDbCommand("SELECT * FROM myRange1", objConn);
// Create new OleDbDataAdapter that is used to build a DataSet
// based on the preceding SQL SELECT statement.
OleDbDataAdapter objAdapter1 = new OleDbDataAdapter();
// Pass the Select command to the adapter.
objAdapter1.SelectCommand = objCmdSelect;
// Create new DataSet to hold information from the worksheet.
DataSet objDataset1 = new DataSet();
// Fill the DataSet with the information from the worksheet.
objAdapter1.Fill(objDataset1, "XLData");
// Bind data to DataGrid control.
DataGrid1.DataSource = objDataset1.Tables[0].DefaultView;
DataGrid1.DataBind();
// Clean up objects.
objConn.Close();
ref to thisLink
i want to import excel to my database . But now i got a very weird problem while importing the data from excel file.
Here is the screen shoot for the excel file
I actually want to import the column of Brand into my database.I can import those record which are AW08 to the dataTable , but when the record is 2006 , the datatable return me empty column.On the other hand the format of brand is general type
Here is the screen shoot of the dataTable
Here is my coding
DataTable dtExcel = new DataTable();
OleDbConnection conn = new OleDbConnection(strConn);
// Initialize an OleDbDataAdapter object.
conn.Open();
OleDbCommand ocmd = new OleDbCommand("select * from [MenShoe $] ", conn);
// Initialize an OleDbDataAdapter object.
OleDbDataAdapter da = new OleDbDataAdapter("select * from [MenShoe $] ", conn);
// Fill the DataTable with data from the Excel spreadsheet.
da.Fill(dtExcel);
Does anyone face this problem before?
Maybe your problem is related to the kind of formatting applied to the BRAND column.
See that AW08 looks like a string and 2006 is treated like a number. Take a look at that.
Try to modify the formatting of the entire column in Excel to use TEXT instead and test the import again.
I'm working on a SharePoint workflow, and the first step requires me to open an Excel workbook and read two things: a range of categories (from a range named, conveniently enough, Categories) and a category index (in the named range CategoryIndex). Categories is a list of roughly 100 cells, and CategoryIndex is a single cell.
I'm using ADO.NET to query the workbook
string connectionString =
"Provider=Microsoft.ACE.OLEDB.12.0;" +
"Data Source=" + temporaryFileName + ";" +
"Extended Properties=\"Excel 12.0 Xml;HDR=YES\"";
OleDbConnection connection = new OleDbConnection(connectionString);
connection.Open();
OleDbCommand categoryIndexCommand = new OleDbCommand();
categoryIndexCommand.Connection = connection;
categoryIndexCommand.CommandText = "Select * From CategoryIndex";
OleDbDataReader indexReader = categoryIndexCommand.ExecuteReader();
if (!indexReader.Read())
throw new Exception("No category selected.");
object indexValue = indexReader[0];
int categoryIndex;
if (!int.TryParse(indexValue.ToString(), out categoryIndex))
throw new Exception("Invalid category manager selected");
OleDbCommand selectCommand = new OleDbCommand();
selectCommand.Connection = connection;
selectCommand.CommandText = "SELECT * FROM Categories";
OleDbDataReader reader = selectCommand.ExecuteReader();
if (!reader.HasRows || categoryIndex >= reader.RecordsAffected)
throw new Exception("Invalid category/category manager selected.");
connection.Close();
Don't judge the code itself too harshly; it's been through a lot. Anyway, the first command never executes correctly. It doesn't throw an exception. It just returns an empty data set. (HasRows is true, and Read() returns false, but there is no data there) The second command works perfectly. These are both named ranges.
They are populated differently, however. There's a web service call that fills up Categories. Those values are displayed in a dropdown box. The selected index goes into CategoryIndex. After hours of banging my head, I decided to write a couple of lines of code so that the dropdown's value goes into a different cell, then I copy the value using a couple of lines of C# into CategoryIndex, so that the data is set identically. That turned out to be a blind alley, too.
Am I missing something? Why would one query work perfectly and the other fail to return any data?
I have found the issue. Excel was apparently unable to parse the value in the cell, so it was returning nothing. What I had to do was adjust the connection string to the following:
string connectionString =
"Provider=Microsoft.ACE.OLEDB.12.0;" +
"Data Source=" + temporaryFileName + ";" +
"Extended Properties=\"Excel 12.0 Xml;HDR=NO;IMEX=1\"";
It would have been helpful if it would have thrown an exception or given any indication of why it was failing, but that's beside the point now. The option IMEX=1 tells Excel to treat all values as strings only. I'm quite capable of parsing my own integers, thankyouverymuch, Excel, so I didn't need its assistance.