Why is OleDB ignoring Excel cells? - c#

Here's the setup:
I have an excel spreadsheet that has a very simple page. It looks like so:
I use the following connection string to access this file:
string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 8.0;HDR=NO\";", fn)
My function to access the file looks like:
try
{
string select = string.Format("SELECT * FROM [{0}$]", tab.PageName);
OleDbDataAdapter adapter = new OleDbDataAdapter(select, con);
DataSet ds = new DataSet();
adapter.Fill(ds, tab.PageName);
// DEBUG: Let's just see what it is getting...
for (int x = 0; x < 13; x++)
{
for (int y = 0; y < 3; y++)
{
Console.Write(ds.Tables[0].Rows[x][y].ToString() + "\t");
}
Console.WriteLine("");
}
}
catch
{ ... }
QUESTION
Why would the code NOT read some cells? Note that there is the text "Profit" at C5. I can read B5 just fine as "Revenue". I can read C6 just fine as an integer value. But Profit seems to vanish.
This isn't such a big problem with the header information, but entire blocks of real data refuse to be read. Instead it returns DBNull, even when the cell contains real, valid, usable data. The cells are all formatted exactly the same between cells that can read and cells that return DBNull.
I'm truly stumped!!!
Any thoughts?

new OleDbConnection("...TypeGuessRows=0;ImportMixedTypes=Text");
I have a hunch you may be experiencing a problem that I had previously.
Try adding those parameters to your connection string.

I was having trouble getting the other answer+comment to work. The only setting needed was the IMEX=1 but it must be nested in single quotes in the Extended Properties, so here's an example of exactly how to format the additional IMEX setting:
connection.ConnectionString =
#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\somepath\somefile.xls;Extended Properties='Excel 8.0;IMEX=1';";

if (ObjFile.Extension == ".xls")
conn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + srcFilePath + ";" + "Extended Properties='Excel 8.0;HDR=YES;'";
if (ObjFile.Extension == ".xlsx")
conn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + srcFilePath + ";" + "Extended Properties='Excel 12.0 Xml;HDR=YES;IMEX=1';";
if (ObjFile.Extension == ".xlsm")
conn = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + srcFilePath + ";Extended Properties='Excel 12.0 Macro;HDR=No;IMEX=1';";

Related

Cannot parse some excel column

Good day!
I try to open and parse excel file into DataSet.
So, i use OleDbConnection:
if (_filePath.Substring(_filePath.LastIndexOf('.')).ToLower() == ".xlsx")
// strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source="
// + _filePath + ";Extended Properties=\"Excel 12.0;HDR=" + HDR + ";IMEX=0\"";
strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source="
+ _filePath + ";Extended Properties=\"Excel 12.0 Xml;HDR=" + HDR + ";IMEX=1;TypeGuessRows=0;ImportMixedTypes=Text;\"";
// strConn="Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + _filePath + ";Extended Properties=Excel 12.0;";
else
strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + _filePath + ";Extended Properties=\"Excel 8.0;HDR=" + HDR + ";IMEX=1\"";
But some column are empty!
The next column parses well (it with same data).
Can you tell me how to fix it?
Then i fill Dataset:
OleDbConnection conn = new OleDbConnection(strConn);
System.Data.DataSet dtSet;
System.Data.OleDb.OleDbDataAdapter oleCommand;
oleCommand = new System.Data.OleDb.OleDbDataAdapter("select * from [" + sheetName + "]", conn);
oleCommand.TableMappings.Add("Table", sheetName);
dtSet = new System.Data.DataSet();
oleCommand.Fill(dtSet);
oleCommand.Dispose();
conn.Close();
return dtSet.Tables[0];
But, some columns are empty!
May be, it happens because excel file has format:
Cell1--------------|Value1------------|
Cell2---|Cell3-----|Value2---|Value4--|
So, dataset fill columns :
Cell1---|-------|--Value1------|-----|
Cell2---|Cell3--|---Empty(!)---|Value4|
So, i need to get Empty(!) column.
About invalid data at column.
I copy and paste this column at right column- and it works!
But,i should use last format, not mine.
HDR="NO";
Maybe you ran into this error:
OleDB & mixed Excel datatypes : missing data
What's the value of 'HDR'? Take a look at the Datatypes of the Columns, maybe they are mixed.

Opening an Excel (created with EPPLUS) with OleDB

I have code from a colleague, this code creates a few excel sheets with Epplus. With my code I would like to add an database extract 10k+/- lines. Because of the large amount of data it takes too long with Epplus, because you need to write each cell. With OleDB it only takes a few seconds. But I can't open a previously created excel by Epplus with OleDB. Even with different connection strings.
This my code works perfect if you separate the two code blocks.
var excelPath = "C:\\test_" + DateTime.Today.ToString("yyyyMMdd_") + DateTime.Now.ToString("hh") + DateTime.Now.Minute.ToString() + ".xlsx";
using (ExcelPackage xlPackage = new ExcelPackage(new FileInfo(excelPath)))
{
ExcelWorksheet worksheet = xlPackage.Workbook.Worksheets.Add("Schedule V");
worksheet.Cell(1, 1).Value = "test";
xlPackage.Save();
xlPackage.Dispose();
}
var strCn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + excelPath + ";Extended Properties='Excel 12.0 Xml';";
using (OleDbConnection conn = new OleDbConnection(strCn))
{
conn.Open();
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = conn;
cmd.CommandText = "CREATE TABLE [table1] (id INT, name VARCHAR, datecol DATE );";
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO [table1](id,name,datecol) VALUES(1,'AAAA','2014-01-01');";
cmd.ExecuteNonQuery();
conn.Close();
}
I tried the following connection strings but they all give the same error:
OleDbException was unhandled, External table is not in the expected
format.
My diffrent connection string I tried:
var strCn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + excelPath + ";Extended Properties='Excel 12.0';";
var strCn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + excelPath + ";Extended Properties='Excel 12.0 Xml';";
var strCn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + excelPath + ";Extended Properties='Excel 12.0 Xml;HDR=YES';";
var strCn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + excelPath + ";Extended Properties='Excel 12.0 Xml;HDR=YES;IMEX=1';";
var strCn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + excelPath + ";Extended Properties='Excel 8.0;HDR=YES';";
var strCn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + excelPath + ";Extended Properties='Excel 8.0;HDR=Yes;IMEX=1';";
What am I doing wrong here?
I guess, it should be like this, rather than hardcoding you should use OleDbConnectionStringBuilder class
OleDbConnectionStringBuilder connectionStringBuilder = new OleDbConnectionStringBuilder();
connectionStringBuilder.Provider = "Microsoft.ACE.OLEDB.12.0";
connectionStringBuilder.DataSource = excelPath; // This is your Excel File Full Path
connectionStringBuilder.Add("Mode", "Read");
const string extendedProperties = "Excel 12.0;IMEX=1;HDR=YES";
connectionStringBuilder.Add("Extended Properties", extendedProperties);
String connectionString = connectionStringBuilder.ToString();
// Create connection object by using the preceding connection string.
using (var objConn = new OleDbConnection(connectionString))
{
// Open connection with the database.
objConn.Open();
// Do operations with your File here
}
I was getting this error consistently with .xlsx files created with EPPlus 4.0.4. I remembered this was working prior to upgrading to EPPlus 4.x. I downgraded to 3.1.3.3 and I no longer get this error.

The Microsoft Jet database engine cannot open the file ''.It is already opened exclusively by another user, or you need permission to view its data"

i am using OLEDB server to read excel file in my ASP.NET MVC project. then i m getting error
"The Microsoft Jet database engine cannot open the file ''.It is already opened exclusively by another user, or you need permission to view its data". same code with different comnnection string of CSV file is work fine but For Excel connectionString i am getting this error. is there anyone know the solution for this please.
My code is:
public JsonResult ImportCSVFiles()
{
HttpPostedFileBase hpf = null;
foreach (string file in Request.Files)
{
hpf = Request.Files[file] as HttpPostedFileBase;
}
string[] FileName;
string filename = hpf.FileName;
string DestinationPath = Server.MapPath("..") + "\\CSVFiles\\";
if (!Directory.Exists(DestinationPath))
{
Directory.CreateDirectory(DestinationPath);
if (System.IO.File.Exists(Server.MapPath("..") + "\\CSVFiles\\" + filename) == false)
{
hpf.SaveAs(DestinationPath + filename);
}
else
{
System.IO.File.Delete(Server.MapPath("..") + "\\CSVFiles\\" + filename);
hpf.SaveAs(DestinationPath + filename);
}
}
else
{
if (System.IO.File.Exists(Server.MapPath("..") + "\\CSVFiles\\" + filename) == false)
{
hpf.SaveAs(DestinationPath + filename);
}
else
{
System.IO.File.Delete(Server.MapPath("..") + "\\CSVFiles\\" + filename);
hpf.SaveAs(DestinationPath + filename);
}
}
bool isFirstRowHeader = true;
string header = isFirstRowHeader ? "Yes" : "No";
string path = "";
string pathOnly = Path.GetDirectoryName(DestinationPath);
string fileName = Path.GetFileName(DestinationPath + "\\" + filename);
string sql = #"SELECT * FROM [" + fileName + "]";
//using (OleDbConnection connection = new OleDbConnection(
// #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + pathOnly +
// ";Extended Properties=\"Text;HDR=" + header + "\""))
using (OleDbConnection connection = new OleDbConnection(
#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + pathOnly +
";Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=1\";"))
using (OleDbCommand command = new OleDbCommand(sql, connection))
using (OleDbDataAdapter adapter = new OleDbDataAdapter(command))
{
DataTable dataTable = new DataTable();
dataTable.Locale = CultureInfo.CurrentCulture;
adapter.Fill(dataTable);
}
}
commented connectionstring is for CSV file and CSV file works fine with same code.
I had the same problem with a program I was recently working on. My solution was to simply take out the extra bits from the connection string. I have no idea why it worked but since it worked for me, it might work for you. This is what your new connection string would look like:
using (OleDbConnection connection = new OleDbConnection(
#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + pathOnly + ";"))
You actually might be able to keep the HDR=Yes bit just because I understand that you might need that to tell it there are headers and I don't think leaving it in would affect it.

Read csv file using [duplicate]

This question already has answers here:
Reading CSV file and storing values into an array
(21 answers)
Closed 9 years ago.
I am using the below two codes to read the csv file but it returns the same error.
'E:\business\business\Document\4112013\20580.csv' is not a valid path. Make sure that the path name is spelled correctly and that you are connected to the server on which the file resides.
I'm not able to fix this issue. Plese help me to solve this
SaveLocation = #"E:\business\business\Document\4112013\20580.csv";
string connStr = "Provider=Microsoft.Jet.OleDb.4.0;Data Source=#" + SaveLocation + ";Extended Properties=\"Text;HDR=YES;FMT=Delimited\"";
OleDbConnection conn = new OleDbConnection(connStr);
conn.Open();
// give full path to the file here
OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM " + SaveLocation, conn);
DataSet ds = new DataSet("QueryCSV");
adapter.Fill(ds);
DataTable dt = ds.Tables[0];
System.Data.OleDb.OleDbDataAdapter MyCommand = default(System.Data.OleDb.OleDbDataAdapter);
System.Data.OleDb.OleDbConnection MyConnection = default(System.Data.OleDb.OleDbConnection);
//MyConnection = new System.Data.OleDb.OleDbConnection("provider=Microsoft.ACE.OLEDB.12.0; " + "data source=" + SaveLocation + "; " + "Extended Properties=Excel 12.0;");
//MyConnection = new System.Data.OleDb.OleDbConnection("provider=Microsoft.ACE.OLEDB.12.0; " + "data source=" + SaveLocation + "; " + "Extended Properties='csv;HDR=Yes;FMT=Delimited(,)';");
MyConnection = new System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OleDb.4.0;Data Source=" + SaveLocation + ";Extended Properties=\"Text;HDR=YES;FMT=Delimited\"");
MyCommand = new System.Data.OleDb.OleDbDataAdapter("select * from [Sheet5$]", MyConnection);
ds = new System.Data.DataSet();
MyCommand.Fill(ds);
This smells more like security issue then wrong path issue.
You can not from ASP.NET web applicaiton access any parts of your hard drive.
This is for security reasons, so potential atacker would not be able to do the same, in case of your site's broken security.
Put you csv file into the your web applicaiton subdirectory, and access it with combination of one of the following properties:
HttpRuntime.AppDomainAppPath
or with
HttpContext.Current.Request.PhysicalApplicationPath
Having relative and not fixed path brings you other benefits, that after upload your aplcation to a server, or to another server, you have not change anything in reagard of this. Evrything keeps working as before.
For moe information look here
You put this as file path, It will work.
string strDataSource = "E:\business\business\Document\4112013\20580.csv";
strDBFile = strDataSource.Substring(0, strDataSource.LastIndexOf('\\'));
mCon.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + strDBFile + ";Extended Properties=\"Text;Excel 12.0;HDR=No;IMEX=1;FMT=Delimited\"";

C# Failing To Import All of the Cells from an Excel Spreadsheet

I am using some legacy code to return an Excel worksheet as a Dataset. However, when I iterate over the resulting data set it seems that not all of the cells are there. The Excel sheet that is being read has some merged cells and I am wondering if that is the problem. Here is the code:
private DataSet Get_Spreadsheet_Data(string strFileName, string strSheetName)
{
DataSet ds = new DataSet();
string strConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + strFileName + ";" + "Extended Properties=Excel 8.0;";
OleDbConnection objConn = new OleDbConnection(strConnectionString);
try
{
objConn.Open();
OleDbCommand objCmdSelect = new OleDbCommand("SELECT * FROM [" + strSheetName + "$]", objConn);
OleDbDataAdapter objAdapter1 = new OleDbDataAdapter();
objAdapter1.SelectCommand = objCmdSelect;
objAdapter1.Fill(ds);
}
catch (Exception Ex)
{
//litOutput.Text = "<span style=\"color:red;\">Exception Occurred pulling data from the spreadsheet.</span><br>Details: " + Ex.Message;
}
finally
{
objConn.Close();
objConn.Dispose();
}
return ds;
}
Is this code malfunctioning? Any advice is appreciated.
string strConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + strFileName + ";" + "Extended Properties=Excel 8.0;";
needed to read:
string strConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + strFileName + ";" + "Extended Properties="Excel 8.0;HDR=NO;IMEX=1;";
and that did the trick!
Have you tried running the same code with an Excel file that doesn't have the merged files?
That is the first thing I would try if I would wonder if merged cells can cause problems filling your dataset...
Edit for clarification:
For debugging purposes: use the same Excel file, only make sure you undo the merging of the cells.
Even better is to start with an excel file with 3 rows and 3 columns:
Row one: Cell A1 with value 'Foo; Cell B1 'Bar', C1 banana.
Row two: Cell A2 Foo1 B2 Bar1 <-- merge those two cells. C2 = Apple.
Row three: Cell A3 with value 'Foo2; Cell B3 'Bar2' C3 Orange <-- to check if the next line is read well after using merged cells...

Categories

Resources