I am reading .xlsx file using c# like this
string strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileName +
";Extended Properties=\"Excel 12.0;HDR=No;IMEX=1\";";
var output = new DataSet();
using (var conn = new OleDbConnection(strConn))
{
conn.Open();
var dt = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
foreach (DataRow row in dt.Rows)
{
string sheet = row["TABLE_NAME"].ToString();
var cmd = new OleDbCommand("SELECT * FROM [+"+sheet+"+]", conn);
cmd.CommandType = CommandType.Text;
OleDbDataAdapter xlAdapter = new OleDbDataAdapter(cmd);
xlAdapter.Fill(output,"School");
}
}
But I am getting error at xlAdapter.Fill(output,"School");
Error is
The Microsoft Office Access database engine could not find the object '+_xlnm.Print_Area+'. Make sure the object exists and that you spell its name and the path name correctly.
I am not able to figure out that what is wrong happening in code.
I believe your sheet is named _xlnm.Print_Area.
Try changing this line
var cmd = new OleDbCommand("SELECT * FROM [+"+sheet+"+]", conn);
to
var cmd = new OleDbCommand("SELECT * FROM ["+sheet+"]", conn);
When you define print area in your sheet "_xlnm.Print_Area" automatic added with your new sheet. Please remove print area form excel sheet or use following code
if (!dr["TABLE_NAME"].ToString().Contains("_xlnm#Print_Area"))
{
obj.SheetName = dr["TABLE_NAME"].ToString();
lst.Add(obj);
}
variable sheet contains value: +_xlnm.Print_Area+
This +_xlnm.Print_Area+ does not actually exists.
Thats why error is comming.
Check with that object.
I would check what you are getting in row["TABLE_NAME"].ToString(); values. Alternatively, you can try OpenXML SDK: How to: Parse and read a large spreadsheet document (Open XML SDK)
Related
i am trying to read excel data to C# using ODBC here is my code
string lstrFileName = "Sheet1";
//string strConnString = "Driver={Microsoft Text Driver (*.txt; *.csv)};Dbq="+path+ ";Extensions=asc,csv,tab,txt;Persist Security Info=False";
string strConnString = "Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};Dbq=E:\\T1.xlsx;Extensions=xls/xlsx;Persist Security Info=False";
DataTable ds;
using (OdbcConnection oConn = new OdbcConnection(strConnString))
{
using (OdbcCommand oCmd = new OdbcCommand())
{
oCmd.Connection = oConn;
oCmd.CommandType = System.Data.CommandType.Text;
oCmd.CommandText = "select A from [" + lstrFileName + "$]";
OdbcDataAdapter oAdap = new OdbcDataAdapter();
oAdap.SelectCommand = oCmd;
ds = new DataTable();
oAdap.Fill(ds);
oAdap.Dispose();
// ds.Dispose();
}
}
my sample data
A
1
2
3
AA
BB
its data table its read 1,2,3 and two blank row
i can understand because of first row its deciding data type , but how can i convert as String and read all row .
Any suggestion .
i Already tried CStr but no help .
For a previous discussion of similar problem here, please check following:
DBNull in non-empty cell when reading Excel file through OleDB
As a workaround, you may also format the column as "text"(i.e. in Excel, select column, right click "Format Cells..."), though this might be impractical if you will process large number of files or if you must not touch the file..
This is partially speculation, but when reading an Excel document as a database, the adapter has to make a judgement on datatypes and usually does a pretty good job. However, because Excel allows mixed datatypes (and databases do not), it occasionally gets it wrong.
My recommendation would to be to not use a data adapter, and just read in every field as an object type. From there, you can easily cast them to strings (StringBuilder, ToString(), etc) or even TryParse into fields you suspect they should be, ignoring the ODBC datatype.
Something like this would be a boilerplate for that:
using (OdbcCommand oCmd = new OdbcCommand())
{
oCmd.Connection = oConn;
oCmd.CommandType = System.Data.CommandType.Text;
oCmd.CommandText = "select A from [" + lstrFileName + "$]";
using (OdbcDataReader reader = oCmd.ExecuteReader())
{
object[] fields = new object[reader.FieldCount];
while (reader.Read())
{
reader.GetValues(fields);
// do something with fields
}
}
}
I've got a Excel 97/03 document that has "blabla" in its A1 cell in sheet "Sheet1". I thought the following should be able to extract it:
string con = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Book1.xls;" + #"Extended Properties='Excel 8.0;HDR=Yes;'";
using (OleDbConnection connection = new OleDbConnection(con))
{
connection.Open();
OleDbDataAdapter da = new OleDbDataAdapter("Select * From [Sheet1$]", connection);
DataTable dt = new DataTable();
da.Fill(dt);
dynamic cellA1 = dt.Rows[0][0].ToString();
But cellA1 is empty (""). Anyone know how to fix this, I should be able to treat it as a database and get cells from it?
"HDR=Yes;" indicates that the first row contains columnnames, not data. "HDR=No;" indicates the opposite. maybe thats the issue.
The datatable is using the first row of data as its headers, to access the A1 cell simply use the name of the first column:
dynamic cellA1 = dt.Columns[0].ToString();
I have a spreadsheet and I want to upload it in a ASP.NET-MVC tool using C# to extract the data then put them on an SQL server database.
I created a function who put the data into a DataSet so I can use it after to put the data into the database.
Here is the function :
public DataSet getData(HttpPostedFileBase file, string path)
{
var fileName = Path.GetFileName(file.FileName);
oledbConn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + path + ";Extended Properties=\"Excel 8.0;HDR=No;IMEX=1\"");
DataSet ds = new DataSet();
OleDbCommand cmd = new OleDbCommand();
OleDbDataAdapter oleda = new OleDbDataAdapter();
oledbConn.Open();
cmd.Connection = oledbConn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT * FROM [Worksheet0$]";
oleda = new OleDbDataAdapter(cmd);
oleda.Fill(ds);
oledbConn.Close();
return ds;
}
Everything is working but when I do a foreach on the dataset and retrieve the data there is a formatting problem.
The values in my spreadsheet are formatted as Numbers, so for example 1.25 turns into 1.3. The cell is showing 1.3 but when I click on it the value is 1.25.
When I check on my dataset the values in it are the one formatted (not the real values), I have for example the 1.3 instead the 1.25.
When I change the columns format before uploading, everything works all right ! But I am looking for an automatic process to do that.
I think you should try to change this library. I recommend you to use ExcelDataReader 2.1.2.3 and here is the NuGet for it: https://www.nuget.org/packages/ExcelDataReader/
I used this library, it is very fast, and lightweight library. and here is my code:
public List<Checklist> Provide()
{
List<Checklist> checklists = new List<Checklist>();
using (var reader = ExcelReaderFactory.CreateOpenXmlReader(m_Stream))
{
while (reader.Read())
{
Checklist checklist = new Checklist();
checklist.Description = reader.GetString(1);
checklist.View = reader.GetString(2);
checklist.Organ = reader.GetString(3);
checklists.Add(checklist);
}
return checklists;
}
}
Thanks to #Nadeem Khouri
I used the ExcelDataReaderLibrary
Here is the working code :
public DataSet getData(string path)
{
FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read);
IExcelDataReader excelReader = ExcelReaderFactory.CreateBinaryReader(stream);
DataSet result = excelReader.AsDataSet();
return result;
}
I have a excel (.xlsm) file with stock markets live data update through the excel add-in "finansu".
When I try to read excel data through the C# application in stock name column it shows the proper stock name but at the value column it does not show any thing. That stock value column is updated live values through the finansu add-in.
Please help me out to read these values as well.
Thanks in advance.
Below is the source code:
connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileName + ";Extended Properties=\"Excel 12.0;HDR=Yes;IMEX=1\";";
query = "SELECT * FROM [RealTime$]";
conn = new OleDbConnection(connString);
if (conn.State == ConnectionState.Closed)
conn.Open();
cmd = new OleDbCommand(query, conn);
da = new OleDbDataAdapter(cmd);
dt = new System.Data.DataTable();
da.Fill(dt);
OLEDB won't be able to retrieve the data you want. I'm not familiar with the finansu add-in, but Excel Interop should be able to get what you need.
Microsoft.Office.Interop.Excel
Sample code:
using Microsoft.Office.Interop.Excel;
using System;
namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
var filename = #"C:\temp\Book1.xlsx";
var excel = new Microsoft.Office.Interop.Excel.Application();
var wb = excel.Workbooks.Open(filename);
Worksheet realtime = wb.Sheets["RealTime"];
foreach (Range row in realtime.UsedRange.Rows)
{
Console.WriteLine("{0}", row.Cells[1, 1].Value); // Column A
Console.WriteLine("{0}", row.Cells[1, 2].Value); // Column B
// etc ...
}
wb.Close(SaveChanges: false);
}
}
}
I am creating a test framework that should read parameters from an excel sheet. I would like to be able to :
Get a row count of test records in the sheet
Get column count
Reference a particular cell eg A23 and read or write values to it.
I found this code on the internet. Its great but it appears to have been coded to work with a form component. I dont necessarily need to show the excel sheet on a datagrid.
This is the code I found. Its working ok but I need to add the functionalities above. Thanks for your help :)
using System.Data;
using System.Data.OleDb;
...
OleDbConnection con = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Book1.xls;Extended Properties=Excel 8.0");
OleDbDataAdapter da = new OleDbDataAdapter("select * from MyObject", con);
DataTable dt = new DataTable();
da.Fill(dt);
Count Row
sheet.Range["A11"].Formula = “COUNT(A1:A10)”;
Count Column
sheet.Range["A12"].Formula = “COUNT(A1:F1)”;
.NET Excel componetn
you can Reference particular cells using this code :
Select * from [Sheet1$A1:B10]
for example above code access to cell A1 to B10
see here
You can use this method:
private DataTable LoadXLS(string filePath)
{
DataTable table = new DataTable();
DataRow row;
try
{
using (OleDbConnection cnLogin = new OleDbConnection())
{
cnLogin.ConnectionString = "provider=Microsoft.Jet.OLEDB.4.0;Data Source='" + filePath + "';Extended Properties=Excel 8.0;";
cnLogin.Open();
string sQuery = "SELECT * FROM [Sheet1$]";
table.Columns.Add("Tags", typeof(string));
table.Columns.Add("ReplaceWords", typeof(string));
OleDbCommand comDB = new OleDbCommand(sQuery, cnLogin);
using (OleDbDataReader drJobs = comDB.ExecuteReader(CommandBehavior.Default))
{
while (drJobs.Read())
{
row = table.NewRow();
row["Tags"] = drJobs[0].ToString();
row["ReplaceWords"] = drJobs[1].ToString();
table.Rows.Add(row);
}
}
}
return table;
}
And use like this:
DataTable dtXLS = LoadXLS(path);
//and do what you need
If you need to write into Excel you need to check this out http://msdn.microsoft.com/en-us/library/dd264733.aspx
an easy way to handle excel files and operations to them is the following one:
add the microsoft.office.interop.excel reference to your project (Add Reference.. => search under the .NET tab => add the reference)
create a new excel application and open the workbook:
Excel.Application application = new Excel.Application();
Excel.Workbook workbook = application.Workbooks.Open(workBookPath);
Excel.Worksheet worksheet = workbook.Sheets[worksheetNumber];
you can get the row and column count with the following lines:
var endColumn = worksheet.Columns.CurrentRegion.EntireColumn.Count;
var endRow = worksheet.Rows.CurrentRegion.EntireRow.Count;***
reading values form a cell or a range of cells can be done in the following way(rowIndex is the number of the row in which the cells you want to read out are):
System.Array values = (System.Array)worksheet.get_Range("A" +
rowIndex.ToString(), "D" + rowIndex.ToString()).Cells.Value;