c# Import excel file - c#

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");

Related

Reading multiple Excel worksheets inside a single xlsx using c# [duplicate]

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...

handling dynamic excel sheets

I am having a case in which I need to import an excel file,having two sheets into the DB. I am using a SSIS package for the same. The issue is,I can make the excel sheet dynamic,by setting the expressions but the sheets into the excel workbook are also changing names. How can I also get to make the sheet names more dynamic.
I have tried using Microsoft.Office.InterOp.excel in my DEV code,but the PROD does not have excel installed on it. Can somebody resolve this for me.
Thanks in advance.
Try adding something similar to the script below, which can be found at Code Spot - Dynamic Sheet Name in SSIS Excel Spreadsheet Imports. It doesn't require Excel to be installed on the machine.
string excelFile = null;
string connectionString = null;
OleDbConnection excelConnection = null;
DataTable tablesInFile = null;
int tableCount = 0;
DataRow tableInFile = null;
string currentTable = null;
int tableIndex = 0;
string[] excelTables = null;
excelFile = Dts.Variables["User::ExcelFile"].Value.ToString();
connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + excelFile + ";Extended Properties=Excel 8.0";
excelConnection = new OleDbConnection(connectionString);
excelConnection.Open();
tablesInFile = excelConnection.GetSchema("Tables");
tableCount = tablesInFile.Rows.Count;
excelTables = new string[tableCount];
foreach (DataRow tableInFile_loopVariable in tablesInFile.Rows)
{
tableInFile = tableInFile_loopVariable;
currentTable = tableInFile["TABLE_NAME"].ToString();
excelTables[tableIndex] = currentTable;
tableIndex += 1;
}
}
Dts.Variables["User::SheetName"].Value = excelTables[0];
Dts.TaskResult = (int)ScriptResults.Success;
I'm using SQL script to load the the Excel file as it is to a staging table, from there it's processed using SSIS / T-SQL, it's relatively fast and reliable. You can download the driver by itself, you don't need office installation to use this method.
/*Drop table if exists*/
IF OBJECT_ID(’table_1', 'U') IS NOT NULL
EXEC ('DROP TABLE table_1')
/*Load using access driver, can probably work with excel too.*/
select *
into [table_1]
from openrowset('MSDASQL'
,'Driver={Microsoft Access Text Driver (*.txt, *.csv)}'
,'select * from 'D:\folder\file.csv' ')

import .xls and get sheet by number

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();

All of a sudden can't open excel file with microsoft.jet.4.0 with c#. I changed nothing at all with the connection string?

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

How to import Data from a Excel to dataset in asp.net page in c#?

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)

Categories

Resources