Excel through OleDb shows numbers differently...depending on whether spreadsheet is open? - c#

I'm opening an Excel worksheet into a DataTable using OleDb like this:
string select = string.Format("SELECT * FROM [{0}$]", worksheetName);
using (var con = new OleDbConnection(connectionString))
using (var adapter = new OleDbDataAdapter(select, con))
{
con.Open();
var dt = new DataTable();
adapter.Fill(dt);
con.Close();
return dt;
}
Then I loop through the rows of the DataTable reading various bits of data like this:
decimal charge;
bool isChargeReadable =
decimal.TryParse(row["Charge"].ToString(), out charge);
I discovered just now that my code was choking on cells with dollar amounts such as "$1100.00", which it can't parse to decimal. Not so surprising...except that this is code that was working perfectly before just now.
Further investigation revealed that if I run this code while the workbook is open, it sees one of those cells as "1100". If I run it while the workbook is closed, it sees "$1100.00".
Why is this happening? Obviously I'll have to rework my code to function while the workbook is closed, but why would it make a difference? I would've thought it would just be reading the saved workbook.
The connection string I'm using is this...
"Provider=Microsoft.Jet.OLEDB.4.0;
Data Source={0};
Extended Properties=""Excel 8.0;HDR=NO;IMEX=1"";"
...where {0} is replaced by the Excel file name, of course.

I've found that my oledb operations work better in excel withOUT an IMEX=number set. Perhaps your problem is there?

Related

closedxml to datatable without looping

at work I've used closedXML in the past to go from a datatable or dataset to excel extremely quickly without looping. Now I need to go the other way but the only documentation I can find on closed XMl or anything else to go from excel to datatable is to loop. I can't imagine with the current demand for speed, the large amounts of data that can go into excel and the widespread use of Office that nobody has figured out a faster way than looping.
Is there a way in closed XML or another reasonably sized, safe library that quickly moves excel to datables or other system.data objects such as datasets without looping?
You can use a plain OleDb connection to read data from a worksheet into a DataTable:
string strExcelConn = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\filename.xlsx;Extended Properties='Excel 12.0 Xml;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;
}
}

Extract Data from Excel File and Store in SQL Server database

I am looking for advice on the best way to parse a Microsoft Excel file and update/store the data into a given SQL Server database. I using ASP.NET MVC so I plan on having a page/view take in an Excel spreadsheet and using that user given file I will need to use C# to parse the data from the columns and update the database based on matches with the spreadsheet column that contains the key column of the database table. The spreadsheet will always be in the same format so I will only need to handle on format. It seems like this could be a pretty common thing I am just looking for the best way to approach this before getting started. I am using Entity Framework in my current application but I don't have to use it.
I found this solution which seems like it could be a good option:
public IEnumerable<MyEntity> ReadEntitiesFromFile( IExcelDataReader reader, string filePath )
{
var myEntities = new List<MyEntity>();
var stream = File.Open( filePath, FileMode.Open, FileAccess.Read );
using ( var reader = ExcelReaderFactory.CreateOpenXmlReader( stream ) )
{
while ( reader.Read() )
{
var myEntity = new MyEntity():
myEntity.MyProperty1 = reader.GetString(1);
myEntity.MyProperty2 = reader.GetInt32(2);
myEntites.Add(myEntity);
}
}
return myEntities;
}
Here is an example of a what a file might look like (Clock# is the key)
So given a file in this format I want to match the user to the data table record using the clock # and update the record with each of the cells information. Each of the columns in the spreadsheet have a relatable column in the data table. All help is much appreciated.
You can use the classes in the namespace Microsoft.Office.Interop.Excel, which abstracts all the solution you found. Instead of me rewriting it, you can check out this article: http://www.codeproject.com/Tips/696864/Working-with-Excel-Using-Csharp.
Better yet, why not bypass the middle man? You can use an existing ETL tool, such as Pentaho, or Talend, or something to go straight from Excel to your database. These types of tools often offer a lot of customization, and are fairly straightforward to use. I've used Pentaho quite a lot for literally what you're describing, and it saved me the head ache of writing the code myself. Unless you want to/need to write it yourself, I think the latter is the best approach.
Try This
public string GetDataTableOfExcel(string file_path)
{
using (OleDbConnection conn = new OleDbConnection())
{
DataTable dt = new DataTable();
string Import_FileName = Server.MapPath(file_path);
//Import_FileName = System.IO.Path.GetDirectoryName(file_path);
string fileExtension = Path.GetExtension(Import_FileName);
if (fileExtension == ".xlsx")
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 [Sheet1$]";
comm.Connection = conn;
using (OleDbDataAdapter da = new OleDbDataAdapter())
{
da.SelectCommand = comm;
da.Fill(dt);
}
}
}
}
Now Your Data in DataTable. You can create insert query from datatable's data.
file_path is excel file's full path with directory name.

reading only a column from disoriented excel file oledb

I have been able to read a normal excel file via oledb, but the task file for my project contains various format issues, like multiple columns merged, a lot of cells under formulae among others, and as a result, the data set has been unable to store the data of excel file. If I manage to read contents of sheet- 'Input tab', cell numbers AF6-AF-24, my job is done, but the excel file is not getting parsed in excel at all, before i process the column out. Help please!
OleDbConnection connExcel = new OleDbConnection("Provider= Microsoft.ACE.OLEDB.12.0;Data Source=P:\\DummyTesterF.xlsx; Extended Properties=\"Excel 12.0;HDR=YES;\"");
OleDbCommand cmdExcel = new OleDbCommand();
OleDbDataAdapter Adapter = new OleDbDataAdapter();
cmdExcel.CommandText = String.Format("SELECT * From ['Input Tab$']");
cmdExcel.Connection = connExcel;
Adapter.SelectCommand = cmdExcel;
DataTable Table = new DataTable();
Adapter.Fill(Table);
Better switch to Office interop instead.

How do I sum all rows of a specific header in an excel file with c#?

I have a excel table with 1 sheet. That sheet has headers in row 1.
One of the headers is Amount.
I want to read all rows from that header and get the sum of it independently of the number or rows, which is never the same, into a variable of type float.
I'm doing this with c#.
I open the workbook, I get the active sheet and then nothing, I get blocked.
How do I go about this?
Rui Martins
You could use OleDB instead of Excel.Interop
string con = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\test.xls;" +
"Extended Properties='Excel 8.0;HDR=Yes;'";
using(OleDbConnection c = new OleDbConnection(con))
{
c.Open();
string selectString = "SELECT SUM(Amount) FROM [Sheet1$]";
using(OleDbCommand cmd1 = new OleDbCommand(selectString))
{
cmd1.Connection = c;
var result = cmd1.ExecuteScalar();
Console.WriteLine(result);
}
}
This example use the old Microsoft.Jet.OleDB.4.0 provider, but works equally with the new Microsoft.ACE.OLEDB.12.0
Take a look at this article, you should be able to loop through the rows and get the total by adding the cell values altogether.
MSDN article on how to retrieve excel cell values.

Reading Data From MS Excel in .net

I have written a piece of code that reads excel data in data table through ado.net. Now i have seen a strange behavior, That the column data type in ms excel is specified as general, but if the 1st row of the excel of that particular column contains some text, ado.net is unable to read numbers in that particular column and if 1st row contains some numeric information ado.net is unable to read textual data of that particular column. here is the code i am using to read data from excel.
string excelConString = #"Provider=Microsoft.Jet.OLEDB.4.0;
Data Source=D:\A.xls;
Extended Properties=""Excel 8.0;HDR=YES;""";
var oleDbConnection = new OleDbConnection(excelConString);
var cmd = oleDbConnection.CreateCommand();
cmd.CommandText = "select * from [WorkSheet$] where ID>=1500";
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
Any help would be appreciated.
Regards
Ahsan Iqbal
change your connectionstring to
string excelConString = #"Provider=Microsoft.Jet.OLEDB.4.0;
Data Source=D:\A.xls;
Extended Properties=""Excel 8.0;HDR=YES;IMEX=1;TypeGuessRows=0;ImportMixedTypes=Text"""

Categories

Resources