OleDbDataAdapter::Fill is not complete cell data - c#

I am reading excel data using the OleDbDataAdapter for doing this I am using the below code. My excel file has 80 rows and 19 columns. Each column represents different languages(e.g English Arabic, Chinese, etc).
Each row has certain strings.
public DataSet ReadExcelFile(string dataSource)
{
DataSet ds = new DataSet();
string connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + dataSource
+ " ; Extended Properties='Excel 12.0; IMEX=1'";
using (OleDbConnection conn = new OleDbConnection(connectionString))
{
conn.Open();
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = conn;
// Get all Sheets in Excel File
DataTable dtSheet = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
// Loop through all Sheets to get data
foreach (DataRow dr in dtSheet.Rows)
{
string sheetName = dr["TABLE_NAME"].ToString();
if (!sheetName.EndsWith("$"))
continue;
// Get all rows from the Sheet
cmd.CommandText = "SELECT * FROM [" + sheetName + "]";
DataTable dt = new DataTable();
dt.TableName = sheetName;
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
da.Fill(dt);
ds.Tables.Add(dt);
}
cmd = null;
conn.Close();
}
return ds;
}
It works perfectly fine except for a few cells. for the few cells table does not have complete string this is happening for the Chinese language:
for example, my string is:
“个性化喂养模式”允许您预置常用的喂养模式。一旦设定好 , 当按“模式”键时 , 它将自动出现在喂养模式列表中。
-----------------------------------------------
您可以创建 , 编辑或删除个性化喂养模式。
-----------------------------------------------
提示 : 个性化喂养模式可能会被默认喂养列表隐藏。
-----------------------------------------------
使用“>”键选择需要的喂养模式。"
But I am getting only:
“个性化喂养模式”允许您预置常用的喂养模式。一旦设定好 , 当按“模式”键时 , 它将自动出现在喂养模式列表中。
-----------------------------------------------
您可以创建 , 编辑或删除个性化喂养模式。
-----------------------------------------------
提示 : 个性化喂养模式可能会被默认喂养列表隐藏。
-----------------------------------------------
The last row is missing.
This is happening only for 3 cell rest cell are coming properly.

It seems that it is being truncated to 255 characters.
According to this Microsoft Oledb truncates the data length to 255 characters
When you use OLEDB providers then the datatype is determined automatically by the provider based on the first 8 rows. If you have lengthy cells in the first 8 rows then data type will be set as text and otherwise it will be memo type which can hold 255 characters only. To overcome this issue either change the registry setting as mentioned in below KB article: http://support.microsoft.com/kb/281517 or use Microsoft.Jet.OLEDB provider to read the data.
Or you may try the OpenXml approach. Parse and read a large spreadsheet document (Open XML SDK)

Related

Read excel Data as string from Excel using ODBC

i am trying to read excel data to C# using ODBC here is my code
string lstrFileName = "Sheet1";
//string strConnString = "Driver={Microsoft Text Driver (*.txt; *.csv)};Dbq="+path+ ";Extensions=asc,csv,tab,txt;Persist Security Info=False";
string strConnString = "Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};Dbq=E:\\T1.xlsx;Extensions=xls/xlsx;Persist Security Info=False";
DataTable ds;
using (OdbcConnection oConn = new OdbcConnection(strConnString))
{
using (OdbcCommand oCmd = new OdbcCommand())
{
oCmd.Connection = oConn;
oCmd.CommandType = System.Data.CommandType.Text;
oCmd.CommandText = "select A from [" + lstrFileName + "$]";
OdbcDataAdapter oAdap = new OdbcDataAdapter();
oAdap.SelectCommand = oCmd;
ds = new DataTable();
oAdap.Fill(ds);
oAdap.Dispose();
// ds.Dispose();
}
}
my sample data
A
1
2
3
AA
BB
its data table its read 1,2,3 and two blank row
i can understand because of first row its deciding data type , but how can i convert as String and read all row .
Any suggestion .
i Already tried CStr but no help .
For a previous discussion of similar problem here, please check following:
DBNull in non-empty cell when reading Excel file through OleDB
As a workaround, you may also format the column as "text"(i.e. in Excel, select column, right click "Format Cells..."), though this might be impractical if you will process large number of files or if you must not touch the file..
This is partially speculation, but when reading an Excel document as a database, the adapter has to make a judgement on datatypes and usually does a pretty good job. However, because Excel allows mixed datatypes (and databases do not), it occasionally gets it wrong.
My recommendation would to be to not use a data adapter, and just read in every field as an object type. From there, you can easily cast them to strings (StringBuilder, ToString(), etc) or even TryParse into fields you suspect they should be, ignoring the ODBC datatype.
Something like this would be a boilerplate for that:
using (OdbcCommand oCmd = new OdbcCommand())
{
oCmd.Connection = oConn;
oCmd.CommandType = System.Data.CommandType.Text;
oCmd.CommandText = "select A from [" + lstrFileName + "$]";
using (OdbcDataReader reader = oCmd.ExecuteReader())
{
object[] fields = new object[reader.FieldCount];
while (reader.Read())
{
reader.GetValues(fields);
// do something with fields
}
}
}

How can I get A1 cell from a 97/03 Excel document with OleDB?

I've got a Excel 97/03 document that has "blabla" in its A1 cell in sheet "Sheet1". I thought the following should be able to extract it:
string con = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Book1.xls;" + #"Extended Properties='Excel 8.0;HDR=Yes;'";
using (OleDbConnection connection = new OleDbConnection(con))
{
connection.Open();
OleDbDataAdapter da = new OleDbDataAdapter("Select * From [Sheet1$]", connection);
DataTable dt = new DataTable();
da.Fill(dt);
dynamic cellA1 = dt.Rows[0][0].ToString();
But cellA1 is empty (""). Anyone know how to fix this, I should be able to treat it as a database and get cells from it?
"HDR=Yes;" indicates that the first row contains columnnames, not data. "HDR=No;" indicates the opposite. maybe thats the issue.
The datatable is using the first row of data as its headers, to access the A1 cell simply use the name of the first column:
dynamic cellA1 = dt.Columns[0].ToString();

How to access Excel data in C#

I am trying to access data from Excel in C#. Ideally I want to put the data into a list or a series collection. I was using this tutorial - http://www.aspsnippets.com/Articles/Read-Excel-file-using-OLEDB-Data-Provider-in-C-Net.aspx.
It was very helpful but I think he missed out the data adapter part. Here is the code I got following his example.
string connectionString = null;
connectionString = "Provider = Microsoft.ACE.OLEDB.12.0; Data Source = P:\\Visual Studio 2012\\Projects\\SmartSheetAPI\\SmartSheetAPI\\bin\\Debug\\OUTPUT.xls; Extended Properties = 'excel 12.0 Xml; HDR=YES; IMEX=1;';";
//Establish Connection
string dataSource = "P:\\Visual Studio 2012\\Projects\\SmartSheetAPI\\SmartSheetAPI\\bin\\Debug\\OUTPUT.xls;";
string excelConnection = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source = " + dataSource + " Extended Properties='Excel 8.0; HDR=Yes'";
OleDbConnection connExcel = new OleDbConnection(connectionString);
OleDbCommand cmdExcel = new OleDbCommand();
cmdExcel.Connection = connExcel;
//Accessing Sheets
connExcel.Open();
DataTable dtExcelSchema;
dtExcelSchema = connExcel.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
connExcel.Close();
//access excel Sheets (tables in database)
DataSet dataset = new DataSet();
string SheetName = dtExcelSchema.Rows[0]["TABLE_NAME"].ToString();
cmdExcel.CommandText = "SELECT * From [" + SheetName + "]";
da.SelectCommand = cmdExcel;
da.Fill(dataset);
connExcel.Close();
If you look at the bottom three lines you will notice he uses da.SelectCommand and da.Fill to fill the dataset. But I think this requires a dataadapter and he doesn't have that in his example. I have tried creating a dataadapter as below:
SqlDataAdapter dataadapter = new SqlDataAdapter();
But I get an error stating: cannot implicitly convert type 'System.Data.OleDb.OleDbCommand' to System.Data.SqlClient.SqlCommand'.
I know it is working right up to the select statement. Can someone help me I basically just want to be able to access the information I am getting in the select statement.
Accessing excel data using Oledb connection is always a headache.You can try third party controls instead, like Aspose.Usage is very simple .You can try the following code after adding the control's reference to your project.
//Creating a file stream containing the Excel file to be opened
FileStream fstream = new FileStream("C:\\book1.xls", FileMode.Open);
//Instantiating a Workbook object
//Opening the Excel file through the file stream
Workbook workbook = new Workbook(fstream);
//Accessing the first worksheet in the Excel file
Worksheet worksheet = workbook.Worksheets[0];
//Exporting the contents of 7 rows and 2 columns starting from 1st cell to DataTable
DataTable dataTable = worksheet.Cells.ExportDataTable(0, 0, 7, 2, true);
//Binding the DataTable with DataGrid
dataGrid1.DataSource = dataTable;
//Closing the file stream to free all resources
fstream.Close();
You need an OleDBDataAdapter, not SqlDataAdapter. So, do this:
OleDBDataAdapter da = new OleDBDataAdapter(cmdExcel);
da.Fill(dataset);
Excel is an OLEDB data source, and so the classes you should be using will be prefixed with OleDb in general, just like the ones for database connectivity and manipulation are prefixed with Sql.
Documentation

OleDB, Misses the first character of data

I have a CSV Reading code for ASP.NET application I maintain. This ASP.NET website is running fine from 3 yrs now, and CSV reading code that use Ole.JetDB.4.0 is doing its work fine, except that once in a while some CSV with more than 4K-5K records create a problem. Usually the problem is that a record at random position [random row] miss the first character of it.
CSV File is just bunch of name and addresses per row, and they are in ASNI Format. CSV is comma seperate, no data have "comma" in data and now enclosing of field in Single or Double quote. Also, it doesn't happen often, We use the same code for say 70K record upload they works fine, but some time say in 3 yrs about 3-4 files have this problem only, we upload about one file daily.
For those who need what I did
using (System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection
("Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties='text;HDR=Yes;FMT=Delimited';Data Source=" + HttpContext.Current.Server.MapPath("/System/SaleList/"))
{
string sql_select = "select * from [" + this.FileName + "]";
System.Data.OleDb.OleDbDataAdapter da = new System.Data.OleDb.OleDbDataAdapter();
da.SelectCommand = new System.Data.OleDb.OleDbCommand(sql_select, conn);
DataSet ds = new DataSet();
// Read the First line of File to know the header
string[] lines = System.IO.File.ReadAllLines(HttpContext.Current.Server.MapPath("/System/SaleList/") + FileName);
string header = "";
if (lines.Length > 0)
header = lines[0];
string[] headers = header.Split(',');
CreateSchema(headers, FileName);
da.Fill(ds, "ListData");
DataTable dt = ds.Tables["ListData"];
}
And this code is working fine except the mention thing. I cut some unrelated part so, might not work by copy paste.
EDIT: More information
I try to use ODBC with Microsoft Text Driver, then I use ACE Driver with OleDB. the result is same with all three drive.
If I swap the problem record, with the preceding Row those rows are read quite well, until the next problem row [if more than one row is having problem in original file], if those are only problem row it works fine.
So from above it looks like that something is there that distract character counter, but how I can ensure it working smooth is still a quiz.
EDIT 2: I have submitted it as bug to Microsoft here : https://connect.microsoft.com/VisualStudio/feedback/details/811869/oledb-ace-driver-12-jet-4-0-or-odbc-text-driver-all-fail-to-read-data-properly-from-csv-text-file
I would suggest you examine a problem file with a hex editor - inspect the line that causes the problem and the line immediately preceding it.
In particular look at the line terminators (CR/LF? CR only? LF only?) and look for any non-printable characters.
Try using ACE Driver instead of JET (it's available on x86 and x64 servers, JET is only x86!)
using (System.Data.OleDb.OleDbConnection conn
= new System.Data.OleDb.OleDbConnection
("Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties="Excel 12.0 Xml;HDR=YES";
Data Source=" + HttpContext.Current.Server.MapPath("/System/SaleList/"))
{
I got the same OleDB, Missing characters of data problem, see here:
The characters go missing because the Microsoft.Jet.OLEDB.4.0 driver
tries to guess the column datatype. In my case its was treating the
data as hexadecimal not alphanumeric.
Problematic oledbProviderString:
oledbProviderString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\"
{0}\";Extended Properties=\"Text;HDR=No;FMT=Delimited\"";
To fix the problem I added TypeGuessRows=0
oledbProviderString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\"
{0}\";Extended Properties=\"Text;HDR=No;FMT=Delimited;TypeGuessRows=0\"";
Repro:
Create a Book1.csv file with this content:
KU88,G6,CC
KU88,F7,CC
Step through this code as pictured above.
private void button1_Click(object sender, EventArgs e)
{
string folder = #"G:\Developers\Folder";
ReproProblem(folder);
}
static string oledbProviderString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\"{0}\";Extended Properties=\"Text;HDR=No;FMT=Delimited\"";
private void ReproProblem(string folderPath)
{
using (OleDbConnection oledbConnection = new OleDbConnection(string.Format(oledbProviderString, folderPath)))
{
string sqlStatement = "Select * from [Book1.csv]";
//open the connection
oledbConnection.Open();
//Create an OleDbDataAdapter for our connection
OleDbDataAdapter adapter = new OleDbDataAdapter(sqlStatement, oledbConnection);
//Create a DataTable and fill it with data
DataTable table = new DataTable();
adapter.Fill(table);
//close the connection
oledbConnection.Close();
}
}
why dont u just use this:
using (System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection
("Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties='text;HDR=Yes;FMT=Delimited';Data Source=" + HttpContext.Current.Server.MapPath("/System/SaleList/"))
{
string sql_select = "select * from [" + this.FileName + "]";
System.Data.OleDb.OleDbDataAdapter da = new System.Data.OleDb.OleDbDataAdapter();
da.SelectCommand = new System.Data.OleDb.OleDbCommand(sql_select, conn);
DataSet ds = new DataSet();
// Read the First line of File to know the header
string[] lines = System.IO.File.ReadAllLines(HttpContext.Current.Server.MapPath("/System/SaleList/") + FileName);
DataTable mdt=new DataTable("ListData");
for (int i = 1; i < lines.Length; i++)
{
string[] sep=lines[i].Split(',');
foreach (var item in sep)
{
mdt.Rows.Add(sep);
}
}
string header = "";
if (lines.Length > 0)
header = lines[0];
string[] headers = header.Split(',');
ds.Tables.Add(mdt);
CreateSchema(headers, FileName);
da.Fill(ds, "ListData");
DataTable dt = mdt;}
i didnt debugged it. i hope there is no problem but if there is im here for you.
thank you very much

how to read data from the 3 row from excel sheet and convert to datatable

i am able read the data fine. but now i have an issue. i need to read data staring from 3 row in an excel sheet. and then convert the data to datatable
how can i set the row postion to start reading data from an excel sheet[to reading starting from 3 row]
example:
excel sheet
1 list of names of the people
2 Employee Name
3 kumar
4 kiran
5 manu
6 manju
so i should start reading data from 2 row in excel. so that
my datatable will have
Employee Name
kumar
kiran
manu
manju
i am using excel 2007.
this is below code i am using is ther any thing tat i need to change.
public static DataTable ExcelToDataTable(string strfilelocation)
{
OleDbConnection excelConn= new OleDbConnection();
DataTable dtPatterns = new DataTable();;
try
{
DataSet ds = new DataSet();
OleDbCommand excelCommand = new OleDbCommand(); OleDbDataAdapter excelDataAdapter = new OleDbDataAdapter();
string excelConnStr = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" + strfilelocation + "; Extended Properties =Excel 8.0;";
excelConn =new OleDbConnection(excelConnStr);
excelConn.Open();
excelCommand = new OleDbCommand("SELECT `Employee Name` as PATTERN FROM [sheet1$]", excelConn);
excelDataAdapter.SelectCommand = excelCommand;
excelDataAdapter.Fill(dtPatterns);
//"dtPatterns.TableName = Patterns";
ds.Tables.Add(dtPatterns);
}
catch (Exception ex)
{
WriteError(ex.Message);
}
finally
{
excelConn.Close();
}
return dtPatterns;
}
any help would greatly appreicated. looking for an a solution
use this query
SELECT `Employee Name` as PATTERN FROM [sheet1$A2:A6]
with HDR=Yes in Connection string

Categories