I am using Excel Data Reader to read some data in to an Entity Framework Database
The code below is working but i need some further refinements
First of all IsFirstRowAsColumnNames does not seem to be working as intended and I have to use .Read instead.
The fudge i had in originally to select a particular sheet was has scuppered plans, can anyone help with this excelReader.Name at the moment is pointless unless i can specifically loop through or select a sheet, which I originally used .Read to achieve hence the conflict.
It would also be nice to refer to the actual column header names to retrieve the data rather than indexes such as var name = reader["applicationname"].ToString() in SQL client;
Is there perhaps a better Extension i could use to read in excel data if i can't achieve the above.
public static void DataLoadAliases(WsiContext context)
{
const string filePath = #"Alias Master.xlsx";
var stream = File.Open(filePath, FileMode.Open, FileAccess.Read);
var excelReader = filePath.Contains(".xlsx")
? ExcelReaderFactory.CreateOpenXmlReader(stream)
: ExcelReaderFactory.CreateBinaryReader(stream);
excelReader.IsFirstRowAsColumnNames = true;
excelReader.Read(); //skip first row
while (excelReader.Read())
{
if (excelReader.Name == "Alias Master")
{
var aliasId = excelReader.GetInt16(0);
var aliasName = excelReader.GetString(1);
//Prevent blank lines coming in from excel;
if (String.IsNullOrEmpty(aliasName)) continue;
context.Aliases.Add(new ApplicationAlias
{
AliasId = aliasId,
Name = aliasName,
});
}
else
{
excelReader.NextResult();
}
}
excelReader.Close();
context.SaveChanges();
}
for .XLSX file i use OpenXML SDK :
http://www.microsoft.com/en-us/download/details.aspx?id=30425
for XLS file i use a OleDbConnection as see below :
OleDbConnection oledbConn = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + FilePath+ ";Extended Properties='Excel 12.0;HDR=NO;IMEX=1;';");
oledbConn.Open();
OleDbCommand cmd = new OleDbCommand();
OleDbDataAdapter oleda = new OleDbDataAdapter();
DataSet ds = new DataSet();
DataTable dt = oledbConn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, null);
string workSheetName = (string)dt.Rows[0]["TABLE_NAME"];
cmd.Connection = oledbConn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT * FROM [" + workSheetName + "]";
oleda = new OleDbDataAdapter(cmd);
oleda.Fill(ds, "Donnees");
oledbConn.Close();
return ds.Tables[0];
DataTable DT = new DataTable();
FileStream stream = File.Open(Filepath, FileMode.Open, FileAccess.Read);
IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
DataSet result = excelReader.AsDataSet();
excelReader.Close();
DT = result.Tables[0];
Related
hi iam new in aspnet core, i have function upload excel file to database and already working, and i want add manual value in column 'status' with value "otw". this value not from excel file so i want to add manual in source code
how i can do it
mytable field.
etd,eta,container,reff,landing_site,sap_code,cases,qty_pl,usd_price,ex_rate,status.
public IActionResult Import(IFormFile postedFile)
{
if (postedFile != null)
{
//Create a Folder.
string path = Path.Combine(this.Environment.WebRootPath, "Uploads");
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
//Save the uploaded Excel file.
string fileName = Path.GetFileName(postedFile.FileName);
string filePath = Path.Combine(path, fileName);
using (FileStream stream = new FileStream(filePath, FileMode.Create))
{
postedFile.CopyTo(stream);
}
//Read the connection string for the Excel file.
string conString = this.Configuration.GetConnectionString("ExcelConString");
DataTable dt = new DataTable();
conString = string.Format(conString, filePath);
using (OleDbConnection connExcel = new OleDbConnection(conString))
{
using (OleDbCommand cmdExcel = new OleDbCommand())
{
using (OleDbDataAdapter odaExcel = new OleDbDataAdapter())
{
cmdExcel.Connection = connExcel;
//Get the name of First Sheet.
connExcel.Open();
DataTable dtExcelSchema;
dtExcelSchema = connExcel
.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
string sheetName = dtExcelSchema.Rows[0]["TABLE_NAME"].ToString();
connExcel.Close();
//Read Data from First Sheet.
connExcel.Open();
cmdExcel.CommandText = "SELECT * From [" + sheetName + "]";
odaExcel.SelectCommand = cmdExcel;
odaExcel.Fill(dt);
connExcel.Close();
}
}
}
//Insert the Data read from the Excel file to Database Table.
conString = this.Configuration.GetConnectionString("DefaultConnection");
using (SqlConnection con = new SqlConnection(conString))
{
using (SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(con))
{
sqlBulkCopy.DestinationTableName = "dbo.Rm";
sqlBulkCopy.ColumnMappings.Add("etd", "etd");
sqlBulkCopy.ColumnMappings.Add("eta", "eta");
sqlBulkCopy.ColumnMappings.Add("container", "container");
sqlBulkCopy.ColumnMappings.Add("reff", "reff");
sqlBulkCopy.ColumnMappings.Add("landing_site", "landing_site");
sqlBulkCopy.ColumnMappings.Add("sap_code", "sap_code");
sqlBulkCopy.ColumnMappings.Add("cases", "cases");
sqlBulkCopy.ColumnMappings.Add("qty_pl", "qty_pl");
sqlBulkCopy.ColumnMappings.Add("usd_price", "usd_price");
sqlBulkCopy.ColumnMappings.Add("ex_rate", "ex_rate");
// in this fiedl i want add manual
sqlBulkCopy.ColumnMappings.Add("status", );
con.Open();
sqlBulkCopy.WriteToServer(dt);
con.Close();
}
}
}
return RedirectToAction("List", new { status = "otw" });
}
worksheet.Cell(1, 1).Value = "ID:";
worksheet.Cell(1, 2).Value = "name:";
worksheet.Cell(1, 3).Value = "surname:";
also which one library are you use for excel
for example me: using OfficeOpenXml;
I want to read a particular column from an excel file and pick each value and put it into a query using c#. I have written a code to read an excel file and show it in datagridview but got stuck while reading a particular column.
Need some help. Below is the code.
private void button1_Click(object sender, EventArgs e)
{
using (OpenFileDialog ofd = new OpenFileDialog() { Filter = "Excel Workbook|*.xls", ValidateNames = true })
{
if (ofd.ShowDialog() == DialogResult.OK)
{
FileStream fs = File.Open(ofd.FileName, FileMode.Open, FileAccess.Read);
IExcelDataReader reader = ExcelReaderFactory.CreateBinaryReader(fs);
var conf = new ExcelDataSetConfiguration
{
ConfigureDataTable = _ => new ExcelDataTableConfiguration
{
UseHeaderRow = true
}
};
dataSet = reader.AsDataSet(conf);
cboSheet.Items.Clear();
foreach (DataTable dt in dataSet.Tables)
cboSheet.Items.Add(dt.TableName);
reader.Close();
}
}
}
private void cboSheet_SelectedIndexChanged(object sender, EventArgs e)
{
dataGridView.DataSource = dataSet.Tables[cboSheet.SelectedIndex];
}
Do you know the excel file will be the same each time? If you can ensure the file will be consistently the same without any column modifications, you can do the following with OfficeOpenXml package.
public IEnumerable<string> ReadFile(string path)
{
using(var file = new FileStream(path, FileMode.Open))
using(var memory = new MemoryStream())
{
file.CopyTo(memory);
using(var package = new ExcelPackage(memory))
if(package.Workbook.Worksheets.Count != 0)
foreach(ExcelWorksheet worksheet in package.Workbook.Worksheets)
for(var row = 0; worksheet.Dimension.Start.Row; row <= worksheet.Dimension.End.Row; row++)
yield return worksheet.Cells[row, 2].Value;
}
}
For brevity I didn't abstract, you could make the code a bit more clear by separating the multiple loop, for worksheet then the rows. As you can see the "2" is representing the specified column. But that would give you a collection you could iterate to dump into your query to process.
You can use ExcelDataReader, that will give you the entire excel content as DataTable
Or you can use OleDbCommand
OleDbConnection conn = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + ExcelPath + "; Extended Properties = 'Excel 12.0;HDR=YES;';");
conn.Open();
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = conn;
cmd.CommandText = SELECT [Colum1], [Colum2] FROM [Sheet1$];
OleDbDataReader reader = cmd.ExecuteReader();
I've been researching all morning and can't find a working solution. I was hoping somebody can tell me the answer.
I am having a user upload a .xls file using a FileUpload, then I want to select all the data from 4 sheets and put in 4 separate datasets. Here is the code I am using:
string strConn = "Driver={Microsoft Excel Driver (*.xls)};DriverId=790;Dbq=" + FileUpload1.PostedFile.FileName;
string query = "SELECT * FROM [{0}]";
DataSet excelDataSet = new DataSet();
OdbcDataAdapter da = new OdbcDataAdapter(query, strConn);
So I have 2 questions,
First Question: How can I select a sheet without knowing its name? The above code is not working, If I substitute {0} with MyFirstSheet$ then it works. I need to know how to select without me knowing what the name will be. Error that I get is:
ERROR [42S02] [Microsoft][ODBC Excel Driver] The Microsoft Jet database engine could not find the object '0}'. Make sure the object exists and that you spell its name and the path name correctly.
Second Question: Is there a way to select all 4 at once and have them put in 4 separate data sets? Currently i was planing to read the file 4 times.
Suggested Code:
String connString = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + FileUpload1.PostedFile.FileName.ToString() + ";Extended Properties=\"Excel 8.0;HDR=No;IMEX=1\"";
OleDbConnection conn = new OleDbConnection(connString);
conn.Open();
String sheet = conn.GetSchema("Tables").Rows[0]["TABLE_NAME"].ToString();
String selectCommand = String.Format(#"SELECT * FROM [{0}]", sheet);
DataSet excelDataSet = new DataSet();
OdbcDataAdapter da = new OdbcDataAdapter(selectCommand, "Driver={Microsoft Excel Driver (*.xls)};DriverId=790;Dbq=" + FileUpload1.PostedFile.FileName);
da.Fill(excelDataSet);
btnLoadCsv.Text = excelDataSet.Tables[0].Rows[10][1].ToString();
You can get a collection of sheets from the workbook:
OleDbConnection conn = new OleDbConnection("Driver={Microsoft Excel Driver (*.xls)};DriverId=790;Dbq=" + FileUpload1.PostedFile.FileName);
conn.Open();
StringBuilder sb = new StringBuilder();
foreach (DataRow row in conn.GetSchema("Tables").Rows)
sb.Append(String.Format(#"SELECT * FROM [{0}];", row["TABLE_NAME"]);
OdbcDataAdapter da = new OdbcDataAdapter(sb.ToString(), conn);
DataSet excelDataSet = new DataSet();
da.Fill(excelDataSet);
excelDataSet.Tables[0].Name = "myTable1";
excelDataSet.Tables[1].Name = "myTable2";
excelDataSet.Tables[2].Name = "myTable3";
//etc...however many sheets you got from Excel (you could loop this too)
This example loops over the row in the schema for "Tables", which equates to sheets in the workbook. Using a compounded SQL SELECT, you get all tables at once into the DataSet, which you can either reference by index (excelDataSet.Tables[0]), or by name if you assign one.
Why don't you try excel data reader, which is an open source project on codeplex? You can view/download the library here http://exceldatareader.codeplex.com/. What you would need to do is get the stream from the FileUploader, and pass it to the library.
The following is a sample extract of the code required
FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read);
//1. Reading from a binary Excel file ('97-2003 format; *.xls)
IExcelDataReader excelReader = ExcelReaderFactory.CreateBinaryReader(stream);
//...
//2. Reading from a OpenXml Excel file (2007 format; *.xlsx)
IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
//...
//3. DataSet - The result of each spreadsheet will be created in the result.Tables
DataSet result = excelReader.AsDataSet();
//...
//4. DataSet - Create column names from first row
excelReader.IsFirstRowAsColumnNames = true;
DataSet result = excelReader.AsDataSet();
//5. Data Reader methods
while (excelReader.Read())
{
//excelReader.GetInt32(0);
}
//6. Free resources (IExcelDataReader is IDisposable)
excelReader.Close();
Below, is the code that loads all sheets into several data tables in one dataset.
//3. DataSet - The result of each spreadsheet will be created in the result.Tables
DataSet result = excelReader.AsDataSet();
I'm hoping someone here can point me in the right direction - I'm trying to create a fairly robust utility program to read the data from an Excel sheet (may be .xls OR .xlsx) into a DataTable as quickly and leanly as possible.
I came up with this routine in VB (although I'd be just as happy with a good C# answer):
Public Shared Function ReadExcelIntoDataTable(ByVal FileName As String, ByVal SheetName As String) As DataTable
Dim RetVal As New DataTable
Dim strConnString As String
strConnString = "Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};DBQ=" & FileName & ";"
Dim strSQL As String
strSQL = "SELECT * FROM [" & SheetName & "$]"
Dim y As New Odbc.OdbcDataAdapter(strSQL, strConnString)
y.Fill(RetVal)
Return RetVal
End Function
I'm wondering if this is the best way to do it or if there are better / more efficent ways (or just more intelligent ways - Maybe Linq / native .Net providers) to use instead?
ALSO, just a quick and silly additional question - Do I need to include code such as y.Dispose() and y = Nothing or will that be taken care of since the variable should die at the end of the routine, right??
Thanks!!
If you want to do the same thing in C# based on CiarĂ¡n Answer
string sSheetName = null;
string sConnection = null;
DataTable dtTablesList = default(DataTable);
OleDbCommand oleExcelCommand = default(OleDbCommand);
OleDbDataReader oleExcelReader = default(OleDbDataReader);
OleDbConnection oleExcelConnection = default(OleDbConnection);
sConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Test.xls;Extended Properties=\"Excel 12.0;HDR=No;IMEX=1\"";
oleExcelConnection = new OleDbConnection(sConnection);
oleExcelConnection.Open();
dtTablesList = oleExcelConnection.GetSchema("Tables");
if (dtTablesList.Rows.Count > 0)
{
sSheetName = dtTablesList.Rows[0]["TABLE_NAME"].ToString();
}
dtTablesList.Clear();
dtTablesList.Dispose();
if (!string.IsNullOrEmpty(sSheetName)) {
oleExcelCommand = oleExcelConnection.CreateCommand();
oleExcelCommand.CommandText = "Select * From [" + sSheetName + "]";
oleExcelCommand.CommandType = CommandType.Text;
oleExcelReader = oleExcelCommand.ExecuteReader();
nOutputRow = 0;
while (oleExcelReader.Read())
{
}
oleExcelReader.Close();
}
oleExcelConnection.Close();
here is another way read Excel into a DataTable without using OLEDB
very quick
Keep in mind that the file ext would have to be .CSV for this to work properly
private static DataTable GetDataTabletFromCSVFile(string csv_file_path)
{
csvData = new DataTable(defaultTableName);
try
{
using (TextFieldParser csvReader = new TextFieldParser(csv_file_path))
{
csvReader.SetDelimiters(new string[]
{
tableDelim
});
csvReader.HasFieldsEnclosedInQuotes = true;
string[] colFields = csvReader.ReadFields();
foreach (string column in colFields)
{
DataColumn datecolumn = new DataColumn(column);
datecolumn.AllowDBNull = true;
csvData.Columns.Add(datecolumn);
}
while (!csvReader.EndOfData)
{
string[] fieldData = csvReader.ReadFields();
//Making empty value as null
for (int i = 0; i < fieldData.Length; i++)
{
if (fieldData[i] == string.Empty)
{
fieldData[i] = string.Empty; //fieldData[i] = null
}
//Skip rows that have any csv header information or blank rows in them
if (fieldData[0].Contains("Disclaimer") || string.IsNullOrEmpty(fieldData[0]))
{
continue;
}
}
csvData.Rows.Add(fieldData);
}
}
}
catch (Exception ex)
{
}
return csvData;
}
I have always used OLEDB for this, something like...
Dim sSheetName As String
Dim sConnection As String
Dim dtTablesList As DataTable
Dim oleExcelCommand As OleDbCommand
Dim oleExcelReader As OleDbDataReader
Dim oleExcelConnection As OleDbConnection
sConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Test.xls;Extended Properties=""Excel 12.0;HDR=No;IMEX=1"""
oleExcelConnection = New OleDbConnection(sConnection)
oleExcelConnection.Open()
dtTablesList = oleExcelConnection.GetSchema("Tables")
If dtTablesList.Rows.Count > 0 Then
sSheetName = dtTablesList.Rows(0)("TABLE_NAME").ToString
End If
dtTablesList.Clear()
dtTablesList.Dispose()
If sSheetName <> "" Then
oleExcelCommand = oleExcelConnection.CreateCommand()
oleExcelCommand.CommandText = "Select * From [" & sSheetName & "]"
oleExcelCommand.CommandType = CommandType.Text
oleExcelReader = oleExcelCommand.ExecuteReader
nOutputRow = 0
While oleExcelReader.Read
End While
oleExcelReader.Close()
End If
oleExcelConnection.Close()
The ACE.OLEDB provider will read both .xls and .xlsx files and I have always found the speed quite good.
public DataTable ImportExceltoDatatable(string filepath)
{
// string sqlquery= "Select * From [SheetName$] Where YourCondition";
string sqlquery = "Select * From [SheetName$] Where Id='ID_007'";
DataSet ds = new DataSet();
string constring = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filepath + ";Extended Properties=\"Excel 12.0;HDR=YES;\"";
OleDbConnection con = new OleDbConnection(constring + "");
OleDbDataAdapter da = new OleDbDataAdapter(sqlquery, con);
da.Fill(ds);
DataTable dt = ds.Tables[0];
return dt;
}
This seemed to work pretty well for me.
private DataTable ReadExcelFile(string sheetName, string path)
{
using (OleDbConnection conn = new OleDbConnection())
{
DataTable dt = new DataTable();
string Import_FileName = path;
string fileExtension = Path.GetExtension(Import_FileName);
if (fileExtension == ".xls")
conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Import_FileName + ";" + "Extended Properties='Excel 8.0;HDR=YES;'";
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 [" + sheetName + "$]";
comm.Connection = conn;
using (OleDbDataAdapter da = new OleDbDataAdapter())
{
da.SelectCommand = comm;
da.Fill(dt);
return dt;
}
}
}
}
You can use OpenXml SDK for *.xlsx files. It works very quickly. I made simple C# IDataReader implementation for this sdk. See here. Now you can easy read excel file to DataTable and you can import excel file to sql server database (use SqlBulkCopy). ExcelDataReader reads very fast. On my machine 10000 records less 3 sec and 60000 less 8 sec.
Read to DataTable example:
class Program
{
static void Main(string[] args)
{
var dt = new DataTable();
using (var reader = new ExcelDataReader(#"data.xlsx"))
dt.Load(reader);
Console.WriteLine("done: " + dt.Rows.Count);
Console.ReadKey();
}
}
I found it pretty easy like this
using System;
using System.Data;
using System.IO;
using Excel;
public DataTable ExcelToDataTableUsingExcelDataReader(string storePath)
{
FileStream stream = File.Open(storePath, FileMode.Open, FileAccess.Read);
string fileExtension = Path.GetExtension(storePath);
IExcelDataReader excelReader = null;
if (fileExtension == ".xls")
{
excelReader = ExcelReaderFactory.CreateBinaryReader(stream);
}
else if (fileExtension == ".xlsx")
{
excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
}
excelReader.IsFirstRowAsColumnNames = true;
DataSet result = excelReader.AsDataSet();
var test = result.Tables[0];
return result.Tables[0];
}
Note: you need to install SharpZipLib package for this
Install-Package SharpZipLib
neat and clean! ;)
This is the way to read from excel oledb
try
{
System.Data.OleDb.OleDbConnection MyConnection;
System.Data.DataSet DtSet;
System.Data.OleDb.OleDbDataAdapter MyCommand;
string strHeader7 = "";
strHeader7 = (hdr7) ? "Yes" : "No";
MyConnection = new System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fn + ";Extended Properties=\"Excel 12.0;HDR=" + strHeader7 + ";IMEX=1\"");
MyCommand = new System.Data.OleDb.OleDbDataAdapter("select * from [" + wks + "$]", MyConnection);
MyCommand.TableMappings.Add("Table", "TestTable");
DtSet = new System.Data.DataSet();
MyCommand.Fill(DtSet);
dgv7.DataSource = DtSet.Tables[0];
MyConnection.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
The below code is tested by myself and is very simple, understandable, usable and fast.
This code, initially takes all sheet names, then puts all tables of that excel file in a DataSet.
public static DataSet ToDataSet(string exceladdress, int startRecord = 0, int maxRecord = -1, string condition = "")
{
DataSet result = new DataSet();
using (OleDbConnection connection = new OleDbConnection(
(exceladdress.TrimEnd().ToLower().EndsWith("x"))
? "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='" + exceladdress + "';" + "Extended Properties='Excel 12.0 Xml;HDR=YES;'"
: "provider=Microsoft.Jet.OLEDB.4.0;Data Source='" + exceladdress + "';Extended Properties=Excel 8.0;"))
try
{
connection.Open();
DataTable schema = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
foreach (DataRow drSheet in schema.Rows)
if (drSheet["TABLE_NAME"].ToString().Contains("$"))
{
string s = drSheet["TABLE_NAME"].ToString();
if (s.StartsWith("'")) s = s.Substring(1, s.Length - 2);
System.Data.OleDb.OleDbDataAdapter command =
new System.Data.OleDb.OleDbDataAdapter(string.Join("", "SELECT * FROM [", s, "] ", condition), connection);
DataTable dt = new DataTable();
if (maxRecord > -1 && startRecord > -1) command.Fill(startRecord, maxRecord, dt);
else command.Fill(dt);
result.Tables.Add(dt);
}
return result;
}
catch (Exception ex) { return null; }
finally { connection.Close(); }
}
Enjoy...
''' <summary>
''' ReadToDataTable reads the given Excel file to a datatable.
''' </summary>
''' <param name="table">The table to be populated.</param>
''' <param name="incomingFileName">The file to attempt to read to.</param>
''' <returns>TRUE if success, FALSE otherwise.</returns>
''' <remarks></remarks>
Public Function ReadToDataTable(ByRef table As DataTable,
incomingFileName As String) As Boolean
Dim returnValue As Boolean = False
Try
Dim sheetName As String = ""
Dim connectionString As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & incomingFileName & ";Extended Properties=""Excel 12.0;HDR=No;IMEX=1"""
Dim tablesInFile As DataTable
Dim oleExcelCommand As OleDbCommand
Dim oleExcelReader As OleDbDataReader
Dim oleExcelConnection As OleDbConnection
oleExcelConnection = New OleDbConnection(connectionString)
oleExcelConnection.Open()
tablesInFile = oleExcelConnection.GetSchema("Tables")
If tablesInFile.Rows.Count > 0 Then
sheetName = tablesInFile.Rows(0)("TABLE_NAME").ToString
End If
If sheetName <> "" Then
oleExcelCommand = oleExcelConnection.CreateCommand()
oleExcelCommand.CommandText = "Select * From [" & sheetName & "]"
oleExcelCommand.CommandType = CommandType.Text
oleExcelReader = oleExcelCommand.ExecuteReader
'Determine what row of the Excel file we are on
Dim currentRowIndex As Integer = 0
While oleExcelReader.Read
'If we are on the First Row, then add the item as Columns in the DataTable
If currentRowIndex = 0 Then
For currentFieldIndex As Integer = 0 To (oleExcelReader.VisibleFieldCount - 1)
Dim currentColumnName As String = oleExcelReader.Item(currentFieldIndex).ToString
table.Columns.Add(currentColumnName, GetType(String))
table.AcceptChanges()
Next
End If
'If we are on a Row with Data, add the data to the SheetTable
If currentRowIndex > 0 Then
Dim newRow As DataRow = table.NewRow
For currentFieldIndex As Integer = 0 To (oleExcelReader.VisibleFieldCount - 1)
Dim currentColumnName As String = table.Columns(currentFieldIndex).ColumnName
newRow(currentColumnName) = oleExcelReader.Item(currentFieldIndex)
If IsDBNull(newRow(currentFieldIndex)) Then
newRow(currentFieldIndex) = ""
End If
Next
table.Rows.Add(newRow)
table.AcceptChanges()
End If
'Increment the CurrentRowIndex
currentRowIndex += 1
End While
oleExcelReader.Close()
End If
oleExcelConnection.Close()
returnValue = True
Catch ex As Exception
'LastError = ex.ToString
Return False
End Try
Return returnValue
End Function
Use the below snippet it will be helpfull.
string POCpath = #"G:\Althaf\abc.xlsx";
string POCConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + POCpath + ";Extended Properties=\"Excel 12.0;HDR=Yes;IMEX=1\";";
OleDbConnection POCcon = new OleDbConnection(POCConnection);
OleDbCommand POCcommand = new OleDbCommand();
DataTable dt = new DataTable();
OleDbDataAdapter POCCommand = new OleDbDataAdapter("select * from [Sheet1$] ", POCcon);
POCCommand.Fill(dt);
Console.WriteLine(dt.Rows.Count);
I've used this method and for me, it is so efficient and fast.
// Step 1. Download NuGet source of Generic Parsing by Andrew Rissing
// Step 2. Reference this to your project
// Step 3. Reference Microsoft.Office.Interop.Excel to your project
// Step 4. Follow the logic below
public static DataTable ExcelSheetToDataTable(string filePath) {
// Save a copy of the Excel file as CSV
var xlApp = new XL.Application();
var xlWbk = xlApp.Workbooks.Open(filePath);
var tempPath =
Path.Combine(Environment
.GetFolderPath(Environment.SpecialFolder.UserProfile)
, "AppData"
, "Local",
, "Temp"
, Path.GetFileNameWithoutExtension(filePath) + ".csv");
xlApp.DisplayAlerts = false;
xlWbk.SaveAs(tempPath, XL.XlFileFormat.xlCSV);
xlWbk.Close(SaveChanges: false);
xlApp.Quit();
// The actual parsing
using (var parser = new GenericParserAdapter(tempPath)) {
parser.FirstRowHasHeader = true;
return parser.GetDataTable();
}
}
Generic Parsing by Andrew Rissing
Here is another way of doing it
public DataSet CreateTable(string source)
{
using (var connection = new OleDbConnection(GetConnectionString(source, true)))
{
var dataSet = new DataSet();
connection.Open();
var schemaTable = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
if (schemaTable == null)
return dataSet;
var sheetName = "";
foreach (DataRow row in schemaTable.Rows)
{
sheetName = row["TABLE_NAME"].ToString();
break;
}
var command = string.Format("SELECT * FROM [{0}$]", sheetName);
var adapter = new OleDbDataAdapter(command, connection);
adapter.TableMappings.Add("TABLE", "TestTable");
adapter.Fill(dataSet);
connection.Close();
return dataSet;
}
}
//
private string GetConnectionString(string source, bool hasHeader)
{
return string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};
Extended Properties=\"Excel 12.0;HDR={1};IMEX=1\"", source, (hasHeader ? "YES" : "NO"));
}
I have a excel sheet which contain records more than 20,000 records and i want to get those data in to a dataset or to a datatable in a very efficient and fast way to in order to process my data. please does any one know how to do this using C# code...
public static DataSet exceldata(string filelocation)
{
DataSet ds = new DataSet();
OleDbCommand excelCommand = new OleDbCommand();OleDbDataAdapter excelDataAdapter = new OleDbDataAdapter();
string excelConnStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filelocation + ";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1""";
OleDbConnection excelConn = new OleDbConnection(excelConnStr);
excelConn.Open();
DataTable dtPatterns = new DataTable();excelCommand = new OleDbCommand("SELECT `PATTERN` as PATTERN, `PLAN` as PLAN FROM [PATTERNS$]", excelConn);
excelDataAdapter.SelectCommand = excelCommand;
excelDataAdapter.Fill(dtPatterns);
"dtPatterns.TableName = Patterns";
ds.Tables.Add(dtPatterns);
return ds;
}
I found the answer by myself. There is a dll called Excel.dll [2.0.1.0] ExcelDataReader. I do not have the link with me, since I got it from one of my friends. I think you can search it from the net and download the exceldatareader.dll
IExcelDataReader iExcelDataReader = null;
FileInfo fileInfo = new FileInfo(FpdUnConLoanUpload.PostedFile.FileName);
string file = fileInfo.Name;
if (file.Split('.')[1].Equals("xls"))
{
iExcelDataReader = ExcelReaderFactory.CreateBinaryReader(oStream);
}
else if (file.Split('.')[1].Equals("xlsx"))
{
iExcelDataReader = ExcelReaderFactory.CreateOpenXmlReader(oStream);
}
iExcelDataReader.IsFirstRowAsColumnNames = true;
DataSet dsUnUpdated = new DataSet();
dsUnUpdated = iExcelDataReader.AsDataSet();
iExcelDataReader.Close();
if (dsUnUpdated != null)
{
}
else
{
lblCmnMesage.Text = "No Data Found In The Excel Sheet!";
}
I think you are surprised with the count 20000. That's not a big count. You can use http://openxmldeveloper.org/ to import and process efficiently without having any dependencies on interop. Only constraint is you need to have the excel in xlsm format(Excel macros)