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();
Related
I importing excel to datatable in my asp.net project.
I have below code:
string excelConString = string.Format(
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};" +
"Extended Properties='Excel 8.0;" +
"IMEX=1;TypeGuessRows=0;ImportMixedTypes=Text;'", filepath);
using (OleDbConnection connection = new OleDbConnection(excelConString))
{
connection.Open();
string worksheet;
worksheet = "Sheet 1$";
string connStr;
connStr = string.Format("Select * FROM `{0}`", worksheet);
OleDbDataAdapter daSheet = new OleDbDataAdapter(connStr, connection);
DataSet dataset = new DataSet();
DataTable table;
table = new DataTable();
daSheet.Fill(table);
dataset.Tables.Add(table);
connStr = string.Format("Select * FROM `{0}$`", worksheet);
table = new DataTable();
daSheet.Fill(table);
dataset.Tables.Add(table);
}
When i run above code in order to import excel, last data always missing because last data has special character like below
"İ,Ö,Ş" etc.
How can i solve this problem.I added below code
"IMEX=1;TypeGuessRows=0;ImportMixedTypes=Text;
however it is not working for me.
Any help will be appreciated.
Thank you
Just answer this question for other readers if any.
If you prefer to handle with POCO directly with Excel file, recommend to use my tool Npoi.Mapper, a convention based mapper between strong typed object and Excel data via NPOI.
Get objects from Excel (XLS or XLSX)
var mapper = new Mapper("Book1.xlsx");
var objs1 = mapper.Take<SampleClass>("sheet2");
// You can take objects from the same sheet with different type.
var objs2 = mapper.Take<AnotherClass>("sheet2");
Export objects to Excel (XLS or XLSX)
//var objects = ...
var mapper = new Mapper();
mapper.Save("test.xlsx", objects, "newSheet", overwrite: false);
Put different types of objects into memory workbook and export together.
var mapper = new Mapper("Book1.xlsx");
mapper.Put(products, "sheet1", true);
mapper.Put(orders, "sheet2", false);
mapper.Save("Book1.xlsx");
This question already has answers here:
Reading multiple excel sheets with different worksheet names
(2 answers)
Closed 8 years ago.
Using c# I can successfully open an excel document and read the data in the first worksheet with the code below. However, my .xlsx has multiple worksheets so I would like to loop through the worksheet collection rather than hard coding the name of each worksheet. Many thanks.
string path = #"C:\Extract\Extract.xlsx";
string connStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=Excel 12.0;";
string sql = "SELECT * FROM [Sheet1$]";
using (OleDbDataAdapter adaptor = new OleDbDataAdapter(sql, connStr))
{
DataSet ds = new DataSet();
adaptor.Fill(ds);
DataTable dt = ds.Tables[0];
}
I used most of the code in the answer here [Reading multiple excel sheets with different worksheet names that was kindly pointed out to me in a comment on my question.
It wouldn't compile for me in VS 2013 though as the DataRow object does not have have the property Item (- r.Item(0).ToString in that code). So I just changed that little bit. It also brought back some worksheet that had Print_Area in its name which wasn't valid so I took that out of my loop. Here is the code as it worked for me.
string path = #"C:\Extract\Extract.xlsx";
string connStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=Excel 12.0;";
DataTable sheets = GetSchemaTable(connStr);
string sql = string.Empty;
DataSet ds = new DataSet();
foreach (DataRow dr in sheets.Rows)
{ //Print_Area
string WorkSheetName = dr["TABLE_NAME"].ToString().Trim();
if (!WorkSheetName.Contains("Print_Area"))
{
sql = "SELECT * FROM [" + WorkSheetName + "]";
ds.Clear();
OleDbDataAdapter data = new OleDbDataAdapter(sql, connStr);
data.Fill(ds);
DataTable dt1 = ds.Tables[0];
foreach (DataRow dr1 in dt1.Rows)
{
//parsing work
}
}
}
static DataTable GetSchemaTable(string connectionString)
{
using (OleDbConnection connection = new
OleDbConnection(connectionString))
{
connection.Open();
DataTable schemaTable = connection.GetOleDbSchemaTable(
OleDbSchemaGuid.Tables,
new object[] { null, null, null, "TABLE" });
return schemaTable;
}
}
I'm about to work on almost the same problem.
I found the guide at http://www.dotnetperls.com/excel quite useful.
In short, to open worksheet no. 3, add the following code after opening the excel workbook:
var worksheet = workbook.Worksheets[3] as
Microsoft.Office.Interop.Excel.Worksheet;
Hope this answered your question.
I'd recommend using EPPlus (available via Nuget https://www.nuget.org/packages/EPPlus/ ) it's a great wrapper tool for working with .xlsx spreadsheets in .Net .In it worksheets are a collection and so you can do what you want by just looping round them, regardless of name or index.
For example,
using (ExcelPackage package = new ExcelPackage(new FileInfo(sourceFilePath)))
{
foreach (var excelWorksheet in package.Workbook.Worksheets)
...
}
You should try the Open XML Format SDK (Nuget: Link). The link below explains both reading and writing Excel documents:
http://www.codeproject.com/Articles/670141/Read-and-Write-Microsoft-Excel-with-Open-XML-SDK
Oh by the way, office doesn't have to be installed to use...
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];
So I'm working on this thing for work, that converts an excel list of instructions into a better looking, formatted word document. I've been connecting to the excel document and then storing the file into a datatable for easier access.
I had just finally gotten the borders and stuff right for my word document when i started getting an error:
External table is not in the expected format.
Here is the full connection algorithm:
public static DataTable getWorkSheet(string excelFile =
"C:\\Users\\Mitch\\Dropbox\\Work tools\\Excel for andrew\\Air Compressor PM's.xlsx") {
string connection = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + excelFile
+ ";Extended Properties='Excel 8.0;HDR=YES;'";
string sql = null;
string worksheetName = null;
string[] Headers = new string[4];
DataTable schema = null;
DataTable worksheet = null;
DataSet workbook = new DataSet();
//Preparing and opening connection
OleDbConnection objconn = new OleDbConnection(connection);
objconn.Open();
//getting the schema data table
schema = objconn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
worksheetName = schema.Rows[0]["Table_Name"].ToString();
//Each worksheet will have a varying name, so the name is just called from
//the dataTable.rows array. Can be later modified to use multiple
//worksheets within a workbook.
sql = "SELECT * FROM[" + worksheetName + "]";
//data adapter
OleDbDataAdapter objAdapter = new OleDbDataAdapter();
//pass the sql
objAdapter.SelectCommand = new OleDbCommand(sql, objconn);
//populate the dataset
objAdapter.Fill(workbook);
//Remove spaces from the headers.
worksheet = workbook.Tables[0];
for (int x = 0; x < Headers.Count(); x++) {
Headers[x] = worksheet.Columns[x].ColumnName;
worksheet.Columns[x].ColumnName = worksheet.Columns[x].ColumnName.Replace(" ", "");
}
return worksheet;
}//end of getWorksheet
EDIT: i pulled up my old code from dropbox previous versions that was definetly working as well as redownload a copy of the excel doc i know was working..... what gives? has something changed in my computer?
You are connecting to a 2007/2010 Excel file (*.xlsx, *.xlsm). You need the updated 2010 drivers (Ace), which can be downloaded for free. The correct connection string can be obtained from http://connectionstrings.com/Excel and http://connectionstrings.com/Excel-2007
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)