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;");
Related
I'm currently facing a problem whereby I don't know how to fix it.
I upload my precompiled project into IIS. Here is my purpose of this page:
User upload a excel file into a folder in the server. ex #"~/PlanQuantityFile/". It did upload successfully.
Problems faced:
It stops when my scripts trying to open the excel file (for extract data purpose) without showing any errors. At line 881 as shown in the image.
Here is few area I had seek for but it still couldn't solve my problem.
Possible Solution:
connection open but never close, so run out of connection. (but I did close it and the scripts stop running before the close statement)
32 bit program calling 64 bit office. (I had limited knowledge on hardware field, don't know what should I do to troubleshoot here)
permission problem. Need to set the permission of ASP.NET account. (I still finding object names for ASP.NET account)
Thanks for anyone who trying to help. Your advice is invaluable.
OleDbConnection oledbConn = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + SaveLocation + ";Extended Properties='Excel 12.0;HDR=YES;IMEX=1;';");
OleDbConnection connExcel = oledbConn;
OleDbCommand cmdExcel = new OleDbCommand();
OleDbDataAdapter oda = new OleDbDataAdapter();
DataTable dt = new DataTable();
cmdExcel.Connection = connExcel;
//Get the name of Sheet
try
{
connExcel.Open();// It stops here without showing errors.
}
catch (Exception ex)
{
ClientScript.RegisterStartupScript(this.GetType(), "myalert", "alert('" + ex.Message + "');", true);
}
The following code returns a datatable for selected filelocation source. Remember to rename the sheetname to "Sheet1".
Use Namespace: using System.Data.OleDb;
Function::::
public DataTable GetExcelinDatatable(string filelocation)
{
DataTable dt = new DataTable();
string connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filelocation + ";Extended Properties=\"Excel 8.0;HDR=YES;\"";
OleDbConnection con = new System.Data.OleDb.OleDbConnection(connectionString);
con.Open();
OleDbDataAdapter da = new System.Data.OleDb.OleDbDataAdapter("select * from [SHEET1$]", con);
da.Fill(dt);
con.Close();
return dt;
}
you can use mentioned function to read the Excel file you have to just pass the path of excel file
private List<DataTable> readExcel(string strXLS)
{
//DataTable dtExcel = getExcelSheetTable();
List<DataTable> SheetsData = new List<DataTable>();
DataTable dtExcel = new DataTable();
DataTable SocialMediaExcel = new DataTable();
string connStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + strXLS + ";Extended Properties=Excel 12.0;";
try
{
OleDbDataAdapter adpt = new OleDbDataAdapter("SELECT * FROM [Sheet1$]", connStr);
adpt.Fill(dtExcel);
SheetsData.Add(dtExcel);
}
catch (Exception ex)
{
throw ex;
}
return SheetsData;
}
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;
I am reading the excel file using C# and below is the code which is working as expected EXCEPT that every time i run the app, I have to close the excel file otherwise I get the below error message:
The Microsoft Access database engine cannot open or write to the file ''. It is already opened exclusively by another user, or you need permission to view and write its data..
my question is: is there a way i close the excel file once i am done reading?
public static DataTable LoadExcelWorkbook(string workbookName)
{
OleDbConnection connection;
string connectionString = String.Format(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=""Excel 8.0;HDR=YES;IMEX=1;""", EXCELFILENAME);
string query = String.Format("select * from [{0}$]", workbookName);
using(OleDbConnection conn = new OleDbConnection(connectionString))
{
connection = new OleDbConnection(connectionString);
connection.Open();
OleDbDataAdapter dataAdapter = new OleDbDataAdapter(query, connectionString);
DataSet dataSet = new DataSet();
dataAdapter.Fill(dataSet);
DataTable myTable = dataSet.Tables[0];
dataAdapter.Dispose();
connection.Close();
dataSet.Dispose();
//CLOSE THE EXCEL FILE?????????
if (myTable != null)
return myTable;
return null;
}
}
use sheet1 name instead of workbook name
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);
}
}
}
}
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