currently I am having sucsess with reading the excel file with my c# ,net 2 winform application. All works well with string and numerical types, but when it comes to date columns it still casts them as string.
I have read that ado.net scans the first eight rows and then uses that to determine the datatype...I have extended my test file to include more than eight rows - but I still have the same results.
thanks for any help you can provide
DataTable tbl = new DataTable();
OleDbConnection dbConnection =
new OleDbConnection (#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\test.xls;Extended Properties=""Excel 8.0;HDR=Yes;""");
dbConnection.Open();
try
{
OleDbDataAdapter dbAdapter = new OleDbDataAdapter("SELECT * FROM [Sheet1$]", dbConnection);
dbAdapter.Fill(tbl);
}
finally
{
dbConnection.Close();
}
.net 2.0, c#, vs2008
Is the field formatted as date in the excel file?
Related
I am trying to access to an old DBase file with Ado.Net C#. I successfully opened file but some string records in table has TAB character like "Some text/TABOther text". Ado.Net driver successfully reads "Some text" and can not read rest of the data. Is there are a way to let Ado.Net read all the content of the cell?
My connection string:
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=DATA DIRECTORY;Extended Properties=dBASE IV;User ID=;Password=;";
Select query:
var sql = "select * from " + "MY_TABLE";
OleDbCommand cmd = new OleDbCommand(sql, con);
con.Open();
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
da.Fill(ds);
I would use VFPOLEDB driver from Microsoft.Jet driver is good for maybe dBase II but not trustable for the later versions (like dBase IV).
DataTable tbl = new DataTable();
new OleDbAdapter("select * from MY_TABLE",
"Provider=VFPOLEDB;Data Source=DATA DIRECTORY",
).Fill(tbl);
And be sure you only have TAB character in between. While xbase databases can store any character in a string field, in C# (contrary to documentation) strings are ASCIIZ strings like in C. Also if that string has NEWLINE character in it, in DataTable you might not see that.
PS: Try posting to Visual-Foxpro tag next time. That one has more interest.
Please do let me know if this is a duplicate; I couldn't find an actual answer..
Found this, related one,
Scientific notation when importing from Excel in .Net
But it is several years old
So I am reading an Excel file, into a DataTable with C#.
My code is as follows:
string conStr = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0;HDR=NO;IMEX=1;\"", filePath);
System.Data.DataTable fileData = new System.Data.DataTable();
using (OleDbConnection connection = new OleDbConnection(conStr))
{
connection.Open();
if (string.IsNullOrEmpty(sheetName))
{
sheetName = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null).Rows[0]["TABLE_NAME"].ToString();
}
string selectCmd = string.Format(sqlSelect, sheetName);
using (OleDbCommand command = new OleDbCommand(selectCmd, connection))
using (OleDbDataAdapter adapter = new OleDbDataAdapter(command))
{
adapter.Fill(fileData);
}
}
So this reads everything in and populates my DataTable
Further through the code I perform validations on some of the content. I'm using RegEx for this.
However, I am running into an issue, where the numbers are being formatted to a scientific notation, or exponential format.
For example, I have 0.000083 and it is being read in as 8.3e-005
So - how can I read in the excel file, and keep the original 0.000083 ?
I'm good with bringing everything in as a string if needed... I've played with the extended properties, but nothing seems to affect how the data is read.
Looking for a solution that negates me having to add each individual cell to the datatable
UPDATE
The other thing I can do, in the meantime, Is convert a scientific-notation to a decimal, and then check that. Though ideally I would like to just bring in without the notation in the first place.
UPDATE:
I have found that this code works! it searches the Excel sheet and only outputs the data I need.
But can anyone explain to me why this works? how does it know that the first line in the spreadsheet is the "index"??
//Coneection String by default empty
string ConStr = "";
//connection string for that file which extantion is .xlsx
ConStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + "C:\\TestExcel.xlsx" + ";Extended Properties='Excel 12.0 XML;HDR=YES;';";
//making query
string query = "SELECT * FROM [lol$] where ID='i2200'";
//Providing connection
OleDbConnection conn = new OleDbConnection(ConStr);
//checking that connection state is closed or not if closed the
//open the connection
if (conn.State == ConnectionState.Closed)
{
conn.Open();
}
//create command object
OleDbCommand cmd = new OleDbCommand(query, conn);
// create a data adapter and get the data into dataadapter
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
DataSet ds = new DataSet();
//fill the Excel data to data set
da.Fill(ds);
foreach (DataRow row in ds.Tables[0].Rows)
{
lblud.Text = "" + row["Hylde"];
}
OLD
I have been trying to do this for several hours now but no matter what i try, I don't end up with the result i want.
So now im "starting from scratch" again. See if I have approached this incorretly.
Question:
I wan't to create a ASPX website that can search my excel sheet for specific data.
Something like Select * from [Sheet1$] where Column A = i2200
then display only Column B and C from that specific row into a Label / two labels.
See picture here: http://itguruen.dk/EXCEL.png
Does anyone have a simple way of doing this?
Thanks in advance!
Jasper
Have you thought about importing the Excel Spreadsheet into a DataTable, and then analyse that DataTable to populate your labels? You can perform SQL queries on DataTables, so you'll be able to extract the exact data you require quite easily (the hardest part will be importing the Excel Spreadsheet into the DataTable).
There's a very detailed report on this process here: http://www.aspsnippets.com/Articles/Read-and-Import-Excel-File-into-DataSet-or-DataTable-using-C-and-VBNet-in-ASPNet.aspx
Update the post so you can see the solution.
Allthough I dont really know why this works??
I'm using oledb to read from excel file.
DataTable sheet1 = new DataTable();
string excelCS = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";" + "Extended Properties=\"Excel 12.0 Xml;HDR=NO;TypeGuessRows=0;ImportMixedTypes=Text\"";
using (OleDbConnection connection = new OleDbConnection(excelCS))
{
connection.Open();
string selectSql = #"SELECT * FROM [Sheet1$]";
using (OleDbDataAdapter adapter = new OleDbDataAdapter(selectSql, connection))
{
adapter.Fill(sheet1);
}
connection.Close();
}
But there is a problem with some cells of the file.
For some cells I get an empty value instead of text. I tried to put some other text into these cells but it didn't work - I'm still getting empty strings.
But after deleting the column and inserting again my application get the right value of cell. Important is that the problem is not with all cells in the column.
Is this a problem with cell format or something? This excel file will be generated by another system so I won't be able to modify it manually.
Has anybody any sugestions what's wrong and what can I do?
Use IMEX = 1 at the end of your connection string. That will fix your problem.
To always use IMEX=1 is a safer way to retrieve data for mixed data
columns. .."
Remember that, sometimes there are some errors involved using IMEX while you're using Update rather than Selecting.
using this method convert Execel to Dataset without Empty String in c#
public static DataSet ConvertExcelToDataTable(string FileName)
{
DataSet ds = new DataSet();
string strConn = "";
strConn = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + FileName + ";Extended Properties=\"Excel 8.0; HDR=YES; IMEX=1;\"";
OleDbDataAdapter da = new OleDbDataAdapter
("SELECT * FROM [Sheet1$]", strConn);
da.Fill(ds);
return ds;
}
it will return dataset.
I had this issue. What I found was that on the cells that returned blank values the data looked like strings, but the rest of the data looked like numbers, so excel stored the strings in a different place as the numbers. I changed the column format to text and all the data was picked up.
This thread might help with changing the format: Format an Excel column (or cell) as Text in C#?
I am reading Excel file using OLEDB in Csharp i have shown the sample excel data what i have
F1 F2 F3 F4
India 23 44 4
China 4 8 Month 6
USA 45 Neg 4
When i read this data and check in my DataTable i get Null values for "Month 6" and "Neg"
where as i can be able get the F1 column correctly... my connection string is as shown
Provider=Microsoft.ACE.OLEDB.12.0;Data Source=[XLSource];Extended Properties=Excel 12.0;
OleDbDataReader dr;
OleDbConnection conExcel = new OleDbConnection();
conExcel.ConnectionString = ConnectionString
conExcel.Open();
OleDbCommand cmdExcel = new OleDbCommand();
cmdExcel.Connection = conExcel;
cmdExcel.CommandText = "SELECT * FROM Sheet1$";
dr = cmdExcel.ExecuteReader();
DataTable dtExcel = new DataTable();
dtExcel.Load(dr);
Try using the IMEX=1 parameter in your connection string (google for more info).
I think what's happening is that Excel is inferring the data type of each column from the first few rows. When it then encounters a value that does not match the inferred data type, it treats it as null.
I had this problem, but rather than setting IMEX=1 I set the registry setting TypeGuessRows to 0 rather than the default 8, I read that IMEX would be needed somewhere but it seems to pick up this registry change either way.
However, I am using the Jet provider rather than Ace so that might make a difference.
For me I found the setting at: Hkey_Local_Machine/Software/Microsoft/Jet/4.0/Engines/Excel/TypeGuessRows
I answered a similar question here. Here I've copied and pasted the same answer for your convenience:
I had this same problem, but was able to work around it without resorting to the Excel COM interface or 3rd party software. It involves a little processing overhead, but appears to be working for me.
First read in the data to get the column names
Then create a new DataSet with each of these columns, setting each of their DataTypes to string.
Read the data in again into this new
dataset. Voila - the scientific
notation is now gone and everything is read in as a string.
Here's some code that illustrates this, and as an added bonus, it's even StyleCopped!
public void ImportSpreadsheet(string path)
{
string extendedProperties = "Excel 12.0;HDR=YES;IMEX=1";
string connectionString = string.Format(
CultureInfo.CurrentCulture,
"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"{1}\"",
path,
extendedProperties);
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
using (OleDbCommand command = connection.CreateCommand())
{
command.CommandText = "SELECT * FROM [Worksheet1$]";
connection.Open();
using (OleDbDataAdapter adapter = new OleDbDataAdapter(command))
using (DataSet columnDataSet = new DataSet())
using (DataSet dataSet = new DataSet())
{
columnDataSet.Locale = CultureInfo.CurrentCulture;
adapter.Fill(columnDataSet);
if (columnDataSet.Tables.Count == 1)
{
var worksheet = columnDataSet.Tables[0];
// Now that we have a valid worksheet read in, with column names, we can create a
// new DataSet with a table that has preset columns that are all of type string.
// This fixes a problem where the OLEDB provider is trying to guess the data types
// of the cells and strange data appears, such as scientific notation on some cells.
dataSet.Tables.Add("WorksheetData");
DataTable tempTable = dataSet.Tables[0];
foreach (DataColumn column in worksheet.Columns)
{
tempTable.Columns.Add(column.ColumnName, typeof(string));
}
adapter.Fill(dataSet, "WorksheetData");
if (dataSet.Tables.Count == 1)
{
worksheet = dataSet.Tables[0];
foreach (var row in worksheet.Rows)
{
// TODO: Consume some data.
}
}
}
}
}
}
}
I answered another question much like this one.
In short, the settings that control the ACE driver behavior are located in the registry at:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\14.0\Access Connectivity Engine\Engines\Excel
Set ImportMixedTypes to Text and set TypeGuessRows to 0 (or some suitably large number like 1000) and you should get the behavior you are expecting.