I have a connection string to read an excel file from my C# project that looks like this..
String ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" +
"Data Source=" + VariableFile + ";" +
"Extended Properties=Excel 8.0;";
and I also have objConn.Open(); to open the file..
The problem is the only time my program will open the file is if I open the Excel file manually and run my program. Can anyone help me to open the file from my C# code instead of having to open it first manually. I get the error message: Could not find installable ISAM when I try to run it without opening the Excel file first.
Thank you
I think your connection string is formatted wrong and the "Could not find installable ISAM" is usually an indication of this.
Try this, it's from a piece of operational code I have:
Excel 2007
string connectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0 Xml;HDR=No;IMEX=1\";", fullPath);
Excel 2003
string connectionString = string.Format("Provider=Microsoft.Jet.OLEDB.4.0; data source={0}; Extended Properties=\"Excel 8.0;HDR=No;IMEX=1\";", fullPath);
I recently had to use this provider for an Azure Web Job where I needed to use an OLEDB Provider rather than the Excel.
You can install the Microsoft.ACE.OLEDB.12.0 Provider using the following setup.
Microsoft Access Database Engine 2010 Redistributable
https://www.microsoft.com/en-us/download/details.aspx?id=13255
Once installed, you can modify the connection string for .xls and .xlsx file extensions.
For example, the following code will convert an Excel file to a DataSet with a DataTable for each Worksheet in the excel file.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Data.OleDb;
using System.Linq;
using System.Net;
...
public DataSet ExcelToDataSet(string excelFilename)
{
var dataSet = new DataSet(excelFilename);
// Setup Connection string based on which excel file format we are using
var excelType = "Excel 8.0";
if (excelFilename.Contains(".xlsx"))
{
excelType = "Excel 12.0 XML";
}
// <add key="Microsoft.ACE.OLEDB" value="Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='{1};HDR=YES;READONLY=TRUE'"/>
var connectionStringFormat = ConfigurationManager.AppSettings["Microsoft.ACE.OLEDB"].ToString();
var excelNamePath = string.Format(#"{0}\{1}", Environment.CurrentDirectory, excelFilename);
var connectionString = string.Format(connectionStringFormat, excelNamePath, excelType);
// Create a connection to the excel file
using (var oleDbConnection = new OleDbConnection(connectionString))
{
// Get the excel's sheet names
oleDbConnection.Open();
var schemaDataTable = (DataTable)oleDbConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
oleDbConnection.Close();
var sheetsName = GetSheetsName(schemaDataTable);
// For each sheet name
OleDbCommand selectCommand = null;
for (var i = 0; i < sheetsName.Count; i++)
{
// Setup select command
selectCommand = new OleDbCommand();
selectCommand.CommandText = "SELECT * FROM [" + sheetsName[i] + "]";
selectCommand.Connection = oleDbConnection;
// Get the data from the sheet
oleDbConnection.Open();
using (var oleDbDataReader = selectCommand.ExecuteReader(CommandBehavior.CloseConnection))
{
// Convert data to DataTable
var dataTable = new DataTable(sheetsName[i].Replace("$", "").Replace("'", ""));
dataTable.Load(oleDbDataReader);
// Add to Dataset
dataSet.Tables.Add(dataTable);
}
}
return dataSet;
}
}
private List<string> GetSheetsName(DataTable schemaDataTable)
{
var sheets = new List<string>();
foreach(var dataRow in schemaDataTable.AsEnumerable())
{
sheets.Add(dataRow.ItemArray[2].ToString());
}
return sheets;
}
There are different providers for connecting to Excel. Maybe you should try using a different one.
Have a look at the examples here:
http://www.connectionstrings.com/excel
Providers for Excel
» Microsoft Jet OLE DB 4.0
» ACE OLEDB 12.0
» .NET Framework Data Provider for OLE DB (OleDbConnection)
» Microsoft Excel ODBC Driver
» .NET Framework Data Provider for ODBC (OdbcConnection)
» .NET xlReader for Microsoft Excel (ExcelConnection)
In your case you should have something like this:
Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\myFolder\myOldExcelFile.xls;Extended Properties="Excel 12.0;HDR=YES";
Following Code will Read the Excel file & Fill DataTable with its data
try
{
string connectionString = string.Empty;
if (Path.GetExtension(ExcelFileName) == ".xlsx")
{
connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + ExcelFileName +
";Extended Properties=Excel 12.0;";
}
else
{
connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + ExcelFileName + ";Extended Properties=Excel 8.0;";
}
OleDbCommand selectCommand = new OleDbCommand();
OleDbConnection connection = new OleDbConnection();
OleDbDataAdapter adapter = new OleDbDataAdapter();
connection.ConnectionString = connectionString;
if (connection.State != ConnectionState.Open)
connection.Open();
DataTable dtSchema = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
List<string> SheetsName = GetSheetsName(dtSchema);
for (int i = 0; i < SheetsName.Count; i++)
{
selectCommand.CommandText = "SELECT * FROM [" + SheetsName[i] + "]";
selectCommand.Connection = connection;
adapter.SelectCommand = selectCommand;
DataTable Sheet = new DataTable();
Sheet.TableName = SheetsName[i].Replace("$", "").Replace("'", "");
adapter.Fill(Sheet);
if (Sheet.Rows.Count > 0)
{
Records.Tables.Add(Sheet);
}
}
}
catch (Exception ex)
{
WriteLog(ex);
}
Other option would be to use a specialized library instead of creating a connection. Take a look on EPPlus, its an open source library to work with excel files in C#. It has worked very good to me.
http://epplus.codeplex.com/
And in this link you can see examples on reading excel files with EPPlus:
http://blog.fryhard.com/archive/2010/10/28/reading-xlsx-files-using-c-and-epplus.aspx
Related
I am trying to read a dbf file in C#, but first I had the error
System.InvalidOperationException: 'The provider' Microsoft.ACE.OLEDB.12.0 'is not registered on the local machine.'
Then I installed Microsoft Access Database Engine 2010 Redistributable and now I have the error
The Microsoft Access database engine cannot open or write to the file 'C:\Users\Emmanuel\Desktop\Proyectos\program'. It is already opened exclusively by another user, or you need permission to view and write its data.'
This is the code I'm using:
var constr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=Excel 12.0;";
var sql = "select * from " + file;
var ds = new DataTable();
using (var con = new OleDbConnection(constr))
{
con.Open();
using (var cmd = new OleDbCommand(sql, con))
{
using (var da = new OleDbDataAdapter(cmd))
{
da.Fill(ds);
}
}
}
Also I've tried this but I have this error
System.Data.Odbc.OdbcException: 'ERROR [HY000] [Microsoft] [ODBC dBase Driver] The external table is not in the expected format.'
string fullPath = path + file;
string sConn = "Driver={Microsoft dBASE Driver (*.dbf)};SourceType=DBF;SourceDB=" + path + ";Exclusive=No; NULL=NO;DELETED=NO;BACKGROUNDFETCH=NO;";
using (OdbcConnection dbConn = new OdbcConnection(sConn))
{
dbConn.Open();
OdbcCommand oCmd = dbConn.CreateCommand();
oCmd.CommandText = "SELECT * FROM " + fullPath;
/* Load data to table */
DataTable dt1 = new DataTable();
dt1.Load(oCmd.ExecuteReader());
dbConn.Close();
}
Hi I am having some issues reading a CSV file with the Jet Database engine. I get this message:
The Microsoft Jet database engine cannot open the file 'C:\Users\mikec\Desktop\'. It is already opened exclusively by another user, or you need permission to view its data.
I have permission to access this folder and file. I have also tried putting in my Visual Studio project and still get the same error. This is my code
string path = #"C:\Users\mikec\Desktop\Book1.csv";
string full = Path.GetFullPath(path);
string file = Path.GetFileName(full);
string dir = Path.GetDirectoryName(full);
//create the "database" connection string
string connString = "Provider=Microsoft.Jet.OLEDB.4.0;"
+ "Data Source=\"" + dir + "\\\";"
+ "Extended Properties=\"Excel 8.0;HDR=Yes;FMT=Delimited\"";
//create the database query
string query = "SELECT * FROM " + file;
//create a DataTable to hold the query results
DataTable dTable = new DataTable();
OleDbConnection con = new OleDbConnection(connString);
//create an OleDbDataAdapter to execute the query
OleDbDataAdapter dAdapter = new OleDbDataAdapter(query, con);
try
{
//fill the DataTable
dAdapter.Fill(dTable);
}
catch (InvalidOperationException e)
{
}
I'm confused to why this is happening I've looked around the Internet and cannot find a solution.
It would be great if anyone out there could point me in the right direction.
Thanks.
I have an excel file and an oledb connection to it. When reading data while file is opened in windows, it throws the following error (at Adapter.Fill method).
However, the code runs fine when file is not opened manually.
private System.Data.DataSet GetExcelData()
{
// Create new DataSet to hold information from the worksheet.
System.Data.DataSet objDataset1 = new System.Data.DataSet();
DataTable dt = new DataTable();
try
{
string path = ConfigurationManager.AppSettings["ExcelFilePath"];
//string connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=Excel 12.0;";
string connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=\"Excel 12.0 Xml;HDR=YES;IMEX=1;\"";
OleDbConnection objConn = new OleDbConnection(connectionString);
objConn.Open();
//String strConString = "SELECT * FROM [Data Version5.2$A2:ZZ] where [Status] = 'aa'";//Status
String strConString = "SELECT * FROM [Data Version5.2$A2:ZZ] where [Status] IS NULL OR [Status]='SubReport'";//Status SubReport
OleDbCommand objCmdSelect = new OleDbCommand(strConString, objConn);
OleDbDataAdapter objAdapter1 = new OleDbDataAdapter();
// Pass the Select command to the adapter.
objAdapter1.SelectCommand = objCmdSelect;
// Fill the DataSet with the information from the work sheet.
objAdapter1.Fill(objDataset1, "ExcelData");
objConn.Close();
}
catch (Exception ex)
{
throw ex;
}
return objDataset1;
}
The error message is
Assuming you don't need to write to the file, try adjusting your connection string to include the read only mode (Mode=Read). I have that in all of mine (where I don't need to write to the file) and I've never had a problem reading from workbooks that are already open:
string connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" +
path + ";Mode=Read;Extended Properties=\"Excel 12.0 Xml;HDR=YES;IMEX=1;\"";
I also don't tend to read Excel files as XML, so the Extended Properties for my connection strings are Excel 12.0;HDR=YES;IMEX=1;
How to read the xls and xlsx files using c# with OpenXML format Without using the OLEDB connection. I am looking for Open XML format procedure.
Below is the code in which I used the OLEDB preocedure. But I am looking for OpenXML format.
public static DataTable ConvretExcelToDataTable(string FilePath)
{
string strConn = string.Empty;
if (FilePath.Trim().EndsWith(".xlsx"))
{
strConn = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0 Xml;HDR=YES;IMEX=1\";", FilePath);
}
else if (FilePath.Trim().EndsWith(".xls"))
{
strConn = string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=1\";", FilePath);
}
OleDbConnection conn = null;
OleDbCommand cmd = null;
OleDbDataAdapter da = null;
DataTable dt = new DataTable();
try
{
conn = new OleDbConnection(strConn);
conn.Open();
cmd = new OleDbCommand(#"SELECT * FROM [Sheet1$]", conn);
cmd.CommandType = CommandType.Text;
da = new OleDbDataAdapter(cmd);
da.Fill(dt);
}
catch (Exception exc)
{
Console.WriteLine(exc.ToString());
Console.ReadLine();
}
finally
{
if (conn.State == ConnectionState.Open)
conn.Close();
conn.Dispose();
cmd.Dispose();
da.Dispose();
}
return dt;
}
Requirement is to implement the above conversion in OpenXML format. Thanks.
You'll want the OpenXml SDK for the xlsx:
http://www.microsoft.com/en-gb/download/details.aspx?id=30425
But for the XLS, you won't be able to use this the XLS format is not based on xml.
I use the NPOI library for accessing older files:
http://npoi.codeplex.com/
The NPOI library also supports xlsx, so this would give you a consistent way of accessing them. Downside is you'll have to loop through sheets/rows/columns manually, and build up the dataset which will probably affect performance if you have large workbooks. If you want to use queries to access the data, OLEDB is the only method I've found.
If you have Excel installed, you could use Microsoft.Office.Interop.Excel;
http://support.microsoft.com/kb/302084
Remove \ from the connection string. You can give as below.
conn = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source="+filepath.ToString() + ";Extended Properties=Excel 12.0 Xml;");
do we need to install Microsoft office in server to run a application to import data from excel file to mssql database ?
any suggestions or ideas ?
the code i used
public partial class _Default : System.Web.UI.Page
{
private String strConnection = "Data Source=MYCBJ017550027;Initial Catalog=MySamplesDB;Integrated Security=True";
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnSend_Click(object sender, EventArgs e)
{
string path = fileuploadExcel.PostedFile.FileName;
string excelConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=Excel 12.0;Persist Security Info=False";
OleDbConnection excelConnection =new OleDbConnection(excelConnectionString);
OleDbCommand cmd = new OleDbCommand("Select [ID],[Name],[Designation] from [Sheet1$]",excelConnection);
excelConnection.Open();
OleDbDataReader dReader;
dReader = cmd.ExecuteReader();
SqlBulkCopy sqlBulk = new SqlBulkCopy(strConnection);
sqlBulk.DestinationTableName = "Excel_table";
sqlBulk.WriteToServer(dReader);
excelConnection.Close();
}
}
If you are reading only xls files then use Microsoft.Jet.OLEDB.4.0 that is inbuilt with your .net framework.
If you are reading xlsx files then use Microsoft.ACE.OLEDB.12.0. The drivers for this can be download freely from Microsoft site. You don't need to install Microsoft officer for interoping.
Use following connection string
string excelConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;
Data Source=" + path + ";Extended Properties=Excel 12.0;HDR=YES";
Download drivers from here
Refer this for running example
As #Romil said you can use the .NET framework for that:
string ConnectionString = string.Format(#"Provider=Microsoft.Jet.OLEDB.4.0; Data Source={0}; Extended Properties=""Excel 8.0;HDR=Yes"";", fileName);
using (OleDbConnection conn = new OleDbConnection(ConnectionString))
{
conn.Open();
DataTable schemaTable = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
foreach (DataRow schemaRow in schemaTable.Rows)
{
string sheet = schemaRow["TABLE_NAME"].ToString();
using (OleDbCommand cmd = new OleDbCommand("SELECT * FROM [" + sheet + "]", conn))
{
cmd.CommandType = CommandType.Text;
DataTable outputTable = new DataTable(sheet);
output.Tables.Add(outputTable);
new OleDbDataAdapter(cmd).Fill(outputTable);
}
}
conn.Close();
}
The problem with jet, is you still have to install the data provider for it (though this is also free) or have office installed for it to work. If you simply need to read an excel file there are plenty of fully managed libs out there that will do the track just fine without the need to install anything.
I've listed a few here. I have used excelreader plenty with good results.
http://excelreader.codeplex.com/
http://epplus.codeplex.com/
Excel reader seem to be light on the documentation side of things. so here is an example of how to use it
IExcelDataReader reader = null;
try
{
using (FileStream stream = new FileStream(ofd.FileName, FileMode.Open))
{
string ext = System.IO.Path.GetExtension(ofd.FileName).Replace(".", "").ToUpper();
if (ext == "XLS")
reader = ExcelReaderFactory.CreateBinaryReader(stream);
else
reader = ExcelReaderFactory.CreateOpenXmlReader(stream);
reader.IsFirstRowAsColumnNames = true;
using (DataSet ds = reader.AsDataSet())
{
foreach (DataRow dr in ds.Tables[0].Rows)
{
ImportData toAdd = new ImportData()
{
Format = dr[0].ToString(),
};
Database.Datastore.InsertObject(toAdd);
}
}
}
}