Reading locked Excel (.xlsx) file, Using C# - c#

Here is my code to read uploaded Excel file. Which is working absolutely fine for past 3 months.
var connectionString = GetOleDbConnectionString(file);
using (var dataAdapter = new OleDbDataAdapter("select * from [Sheet1$]", connectionString))
{
dataAdapter.Fill(ds, tableCount.ToString());
}
private static string GetOleDbConnectionString(string file)
{
var fileExtension = Path.GetExtension(file);
if (fileExtension.EqualsCCIC(".xlsx"))
{
return #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=Excel 12.0;".F(file);
}
}
Problem: Uploaded excel file got "StartDate" as first column. But this column also has employee name along with dates (I need to read this employee name to process this sheet).
I came across one new excel file (Excel2007 .xlsx). When I upload new file (Which has both employee name and dates) it is only reading dates from the column and ignoring employee names. my dataset showing (While debugging) those cells in data table as empty strings. According to business logic I need to know which employee these dates belongs to. I removed locks for entire sheet(cell formatting>>Protection>> lock) but still no use. How can I solve this problem? I have no clue...
It is successfully reading old files (2007 .xlsx) I didn't understand what is it that makes OLEDB to hide strings in Date column?

So you're saying that the new excel file is the issue? If so...
check the data in the file (particularly the first 8 rows in the employee name column)
copy the data from the new file to a file that is known to work
Accessing Excel Spreadsheet with C# occasionally returns blank value for some cells
Check out ABHI's answer in the above link (in particular points 1. and 2.)

Related

Can't read file after 8th row EXCEL OLE DB

I can't read this excel file of mine after the 8th row. I am using a OLEDB connection to access it from a c# script task inside a SSIS package :
strCoExcel = "Provider = Microsoft.ACE.OLEDB.12.0;Mode=Read;Data Source =" + Path.Combine((string)Dts.Variables["PathINPUT"].Value, Dts.Variables["FileNameForEach"].Value.ToString()) + ";Extended Properties=\"Excel 12.0 Xml;HDR=NO;ImportMixedTypes=Text;TypeGuessRows=0;IMEX=1;\"";
//Gathering data from the renamed sheet
OleDbDataAdapter adapter = new OleDbDataAdapter("Select * from [DataTQT$]", coExcel);
DataTable data = new DataTable();
adapter.Fill(data);
What is wrong:
Some excel files are opened and everything is fine but others do not produce any rows or only 8.
I tried the following:
-HDR no/yes
-IMEX =1 doesnt change anything
-nor do ImportMixedTypes=Text;TypeGuessRows=0
-setting all the cell from the excel file to standard or text field
any help ?
OK so the final answer for me was not in this piece of code as suspected by others.
This data goes into a SQL database and the columns were not big enough for the data i wanted to insert. I modified the table and now everything works fine.

How to solve Excel opening Error Generated by EPPlus .Net library

I am generating several excel copies from a template (its really big).
For that First I am taking the template from a file location, then based on a loop for every iteration I am creating a new ExcelPackage(newFile,Template).
After that I am taking the exact ExcelWorksheet that I have to edit.
Then after editing I am Saving as the file as newFile. The time of opening the saved file Two problem is occurring:
If there is no Excel instance is running on the PC then the saved file is opening but with no data.
If the Excel instance is running then the saved file is opening with Warning message but working. "Problem with some content with Excel. Do you want us to recover?" and "Excel was able to recover some unreadable content "
string templateExcel = #"Location\template.xlsx";
FileInfo templateFile = new FileInfo(#"Location\newFile.xlsx");
using (FileStream templateExcelStream = File.OpenRead(templateExcel))
{
using (ExcelPackage copyExcel = new ExcelPackage(templateExcelStream))
{
ExcelWorksheet presentWorkSheet = copyExcel.Workbook.Worksheets["Name"];
presentWorkSheet.Cells[4, 2].Value = Value from condition;
copyExcel.SaveAs(templateFile);
}
}
Thanks all of you for your valuable time. I got the solution.
For me the issue was in the template itself as it contained invalid references to lookup tables. I found this in Formula -> Name Manager.
I suggest that you check the template if you face this issue.

Query an Excel spreadsheet

I have a project where I need to query an Excel spreadsheet. Basically I need to read a two column Excel spreadsheet into a dictionary table. I have a database of error codes and descriptions for each code. The project requires Excel (Excel 2007 compatible .xlsx) because the user wants to add new Key/Description pairs by editing an Excel spread sheet.
The idea is that I am going to get a list of error codes and I simply want to be able to display a table in a worksheet with error code and the associated description from the Excel spreadsheet, or no description found.
I figure if I can get the table (which is not very long) into a dictionary table the rest would straight forward but I cannot even find a starting point using the current version C# and 4.5.2 .NET API. I just need to open the worksheet and read the two column table into a dictionary table and I am off to the races.
Can someone please get me started in the right direction please?
You can probably use OleDbConnection to get the data from Excel.
OleDbConnection con = new OleDbConnection("provider=Microsoft.Jet.OLEDB.4.0;data source="
+ xlsx file with path
+ ";Extended Properties=Excel 8.0;");
StringBuilder stbQuery = new StringBuilder();
stbQuery.Append("SELECT * FROM [" + SHEETNAME_HERE + "$A1:B65]");
OleDbDataAdapter adp = new OleDbDataAdapter(stbQuery.ToString(), con);
DataSet dsXLS = new DataSet();
adp.Fill(dsXLS);
Once you have the data filled up, you can fetch the data in dictionary or any other object of List Enumerable.

Read a cell (or range of cells) directly from an open workbook in Excel using C#? [duplicate]

Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
Is there a free or open source library to read Excel files (.xls) directly from a C# program?
It does not need to be too fancy, just to select a worksheet and read the data as strings. So far, I've been using Export to Unicode text function of Excel, and parsing the resulting (tab-delimited) file, but I'd like to eliminate the manual step.
var fileName = string.Format("{0}\\fileNameHere", Directory.GetCurrentDirectory());
var connectionString = string.Format("Provider=Microsoft.Jet.OLEDB.4.0; data source={0}; Extended Properties=Excel 8.0;", fileName);
var adapter = new OleDbDataAdapter("SELECT * FROM [workSheetNameHere$]", connectionString);
var ds = new DataSet();
adapter.Fill(ds, "anyNameHere");
DataTable data = ds.Tables["anyNameHere"];
This is what I usually use. It is a little different because I usually stick a AsEnumerable() at the edit of the tables:
var data = ds.Tables["anyNameHere"].AsEnumerable();
as this lets me use LINQ to search and build structs from the fields.
var query = data.Where(x => x.Field<string>("phoneNumber") != string.Empty).Select(x =>
new MyContact
{
firstName= x.Field<string>("First Name"),
lastName = x.Field<string>("Last Name"),
phoneNumber =x.Field<string>("Phone Number"),
});
If it is just simple data contained in the Excel file you can read the data via ADO.NET. See the connection strings listed here:
http://www.connectionstrings.com/?carrier=excel2007
or
http://www.connectionstrings.com/?carrier=excel
-Ryan
Update: then you can just read the worksheet via something like select * from [Sheet1$]
The ADO.NET approach is quick and easy, but it has a few quirks which you should be aware of, especially regarding how DataTypes are handled.
This excellent article will help you avoid some common pitfalls:
http://blog.lab49.com/archives/196
This is what I used for Excel 2003:
Dictionary<string, string> props = new Dictionary<string, string>();
props["Provider"] = "Microsoft.Jet.OLEDB.4.0";
props["Data Source"] = repFile;
props["Extended Properties"] = "Excel 8.0";
StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<string, string> prop in props)
{
sb.Append(prop.Key);
sb.Append('=');
sb.Append(prop.Value);
sb.Append(';');
}
string properties = sb.ToString();
using (OleDbConnection conn = new OleDbConnection(properties))
{
conn.Open();
DataSet ds = new DataSet();
string columns = String.Join(",", columnNames.ToArray());
using (OleDbDataAdapter da = new OleDbDataAdapter(
"SELECT " + columns + " FROM [" + worksheet + "$]", conn))
{
DataTable dt = new DataTable(tableName);
da.Fill(dt);
ds.Tables.Add(dt);
}
}
How about Excel Data Reader?
http://exceldatareader.codeplex.com/
I've used in it anger, in a production environment, to pull large amounts of data from a variety of Excel files into SQL Server Compact. It works very well and it's rather robust.
Here's some code I wrote in C# using .NET 1.1 a few years ago. Not sure if this would be exactly what you need (and may not be my best code :)).
using System;
using System.Data;
using System.Data.OleDb;
namespace ExportExcelToAccess
{
/// <summary>
/// Summary description for ExcelHelper.
/// </summary>
public sealed class ExcelHelper
{
private const string CONNECTION_STRING = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=<FILENAME>;Extended Properties=\"Excel 8.0;HDR=Yes;\";";
public static DataTable GetDataTableFromExcelFile(string fullFileName, ref string sheetName)
{
OleDbConnection objConnection = new OleDbConnection();
objConnection = new OleDbConnection(CONNECTION_STRING.Replace("<FILENAME>", fullFileName));
DataSet dsImport = new DataSet();
try
{
objConnection.Open();
DataTable dtSchema = objConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
if( (null == dtSchema) || ( dtSchema.Rows.Count <= 0 ) )
{
//raise exception if needed
}
if( (null != sheetName) && (0 != sheetName.Length))
{
if( !CheckIfSheetNameExists(sheetName, dtSchema) )
{
//raise exception if needed
}
}
else
{
//Reading the first sheet name from the Excel file.
sheetName = dtSchema.Rows[0]["TABLE_NAME"].ToString();
}
new OleDbDataAdapter("SELECT * FROM [" + sheetName + "]", objConnection ).Fill(dsImport);
}
catch (Exception)
{
//raise exception if needed
}
finally
{
// Clean up.
if(objConnection != null)
{
objConnection.Close();
objConnection.Dispose();
}
}
return dsImport.Tables[0];
#region Commented code for importing data from CSV file.
// string strConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" +"Data Source=" + System.IO.Path.GetDirectoryName(fullFileName) +";" +"Extended Properties=\"Text;HDR=YES;FMT=Delimited\"";
//
// System.Data.OleDb.OleDbConnection conText = new System.Data.OleDb.OleDbConnection(strConnectionString);
// new System.Data.OleDb.OleDbDataAdapter("SELECT * FROM " + System.IO.Path.GetFileName(fullFileName).Replace(".", "#"), conText).Fill(dsImport);
// return dsImport.Tables[0];
#endregion
}
/// <summary>
/// This method checks if the user entered sheetName exists in the Schema Table
/// </summary>
/// <param name="sheetName">Sheet name to be verified</param>
/// <param name="dtSchema">schema table </param>
private static bool CheckIfSheetNameExists(string sheetName, DataTable dtSchema)
{
foreach(DataRow dataRow in dtSchema.Rows)
{
if( sheetName == dataRow["TABLE_NAME"].ToString() )
{
return true;
}
}
return false;
}
}
}
Koogra is an open-source component written in C# that reads and writes Excel files.
While you did specifically ask for .xls, implying the older file formats, for the OpenXML formats (e.g. xlsx) I highly recommend the OpenXML SDK (http://msdn.microsoft.com/en-us/library/bb448854.aspx)
I did a lot of reading from Excel files in C# a while ago, and we used two approaches:
The COM API, where you access Excel's objects directly and manipulate them through methods and properties
The ODBC driver that allows to use Excel like a database.
The latter approach was much faster: reading a big table with 20 columns and 200 lines would take 30 seconds via COM, and half a second via ODBC. So I would recommend the database approach if all you need is the data.
Cheers,
Carl
ExcelMapper is an open source tool (http://code.google.com/p/excelmapper/) that can be used to read Excel worksheets as Strongly Typed Objects. It supports both xls and xlsx formats.
I want to show a simple method to read xls/xlsx file with .NET. I hope that the following will be helpful for you.
private DataTable ReadExcelToTable(string path)
{
//Connection String
string connstring = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties='Excel 8.0;HDR=NO;IMEX=1';";
//the same name
//string connstring = Provider=Microsoft.JET.OLEDB.4.0;Data Source=" + path + //";Extended Properties='Excel 8.0;HDR=NO;IMEX=1';";
using(OleDbConnection conn = new OleDbConnection(connstring))
{
conn.Open();
//Get All Sheets Name
DataTable sheetsName = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables,new object[]{null,null,null,"Table"});
//Get the First Sheet Name
string firstSheetName = sheetsName.Rows[0][2].ToString();
//Query String
string sql = string.Format("SELECT * FROM [{0}]",firstSheetName);
OleDbDataAdapter ada =new OleDbDataAdapter(sql,connstring);
DataSet set = new DataSet();
ada.Fill(set);
return set.Tables[0];
}
}
Code is from article: http://www.c-sharpcorner.com/uploadfile/d2dcfc/read-excel-file-with-net/. You can get more details from it.
Not free, but with the latest Office there's a very nice automation .Net API. (there has been an API for a long while but was nasty COM) You can do everything you want / need in code all while the Office app remains a hidden background process.
Forgive me if I am off-base here, but isn't this what the Office PIA's are for?
Lately, partly to get better at LINQ.... I've been using Excel's automation API to save the file as XML Spreadsheet and then get process that file using LINQ to XML.
SpreadsheetGear for .NET is an Excel compatible spreadsheet component for .NET. You can see what our customers say about performance on the right hand side of our product page. You can try it yourself with the free, fully-functional evaluation.
SmartXLS is another excel spreadsheet component which support most features of excel Charts,formulas engines, and can read/write the excel2007 openxml format.
The .NET component Excel Reader .NET may satisfy your requirement. It's good enought for reading XLSX and XLS files. So try it from:
http://www.devtriogroup.com/ExcelReader
I recommend the FileHelpers Library which is a free and easy to use .NET library to import/export data from EXCEL, fixed length or delimited records in files, strings or streams + More.
The Excel Data Link Documentation Section
http://filehelpers.sourceforge.net/example_exceldatalink.html
You can try using this open source solution that makes dealing with Excel a lot more cleaner.
http://excelwrapperdotnet.codeplex.com/
SpreadsheetGear is awesome. Yes it's an expense, but compared to twiddling with these other solutions, it's worth the cost. It is fast, reliable, very comprehensive, and I have to say after using this product in my fulltime software job for over a year and a half, their customer support is fantastic!
The solution that we used, needed to:
Allow Reading/Writing of Excel produced files
Be Fast in performance (not like using COMs)
Be MS Office Independent (needed to be usable without clients having MS Office installed)
Be Free or Open Source (but actively developed)
There are several choices, but we found NPoi (.NET port of Java's long existing Poi open source project) to be the best:
http://npoi.codeplex.com/
It also allows working with .doc and .ppt file formats
If it's just tabular data. I would recommend file data helpers by Marcos Melli which can be downloaded here.
Late to the party, but I'm a fan of LinqToExcel
you could write an excel spreadsheet that loads a given excel spreadsheet and saves it as csv (rather than doing it manually).
then you could automate that from c#.
and once its in csv, the c# program can grok that.
(also, if someone asks you to program in excel, it's best to pretend you don't know how)
(edit: ah yes, rob and ryan are both right)
I know that people have been making an Excel "extension" for this purpose.
You more or less make a button in Excel that says "Export to Program X", and then export and send off the data in a format the program can read.
http://msdn.microsoft.com/en-us/library/ms186213.aspx should be a good place to start.
Good luck
Just did a quick demo project that required managing some excel files. The .NET component from GemBox software was adequate for my needs. It has a free version with a few limitations.
http://www.gemboxsoftware.com/GBSpreadsheet.htm
Excel Package is an open-source (GPL) component for reading/writing Excel 2007 files. I used it on a small project, and the API is straightforward. Works with XLSX only (Excel 200&), not with XLS.
The source code also seems well-organized and easy to get around (if you need to expand functionality or fix minor issues as I did).
At first, I tried the ADO.Net (Excel connection string) approach, but it was fraught with nasty hacks -- for instance if second row contains a number, it will return ints for all fields in the column below and quietly drop any data that doesn't fit.
We use ClosedXML in rather large systems.
Free
Easy to install
Straight forward coding
Very responsive support
Developer team is extremly open to new suggestions. Often new features and bug fixes are implemented within the same week
Take.io Spreadsheet will do this work for you, and at no charge. Just take a look at this.
I just used ExcelLibrary to load an .xls spreadsheet into a DataSet. Worked great for me.

Can a .csv file be used as a data source in Visual Studio 2008?

I'm pretty new to C# and Visual Studio. I'm writing a small program that will read a .csv file and then write the records read to a SQL Server database table.
I can manually parse the .csv file, but I was wondering if it is possible to somehow "describe" the .csv file to Visual Studio so that I can use it as a data source? I should mention that the first two lines in the .csv file contain header information and the following lines are the actual comma-delimited data.
Also, I should mention that this program is a stand-alone console program with no user interface.
This is a great example of using the power of LINQ. Here's a quick reference with an example of how to do it.
The run down is this. You can read in your CSV to a string array, then use LINQ to query against that collection. As Reed points out though, you'll have to code around your header line, as it will throw off your query.
You can also use the TextFieldParser too to handle escaping commas. Here's an example on thinqlinq that uses the TextFieldParser to parse the file, and a LINQ query to get the results. It even has a unit test to make sure escaped commas are handled.
If you have a 2 line header, it's not a standard CSV file.
In this case, the automatic tools won't work, and you'll have to revert to parsing the file manually.
If you want to remove one of the header lines, you might be able to use this technique of parsing CSV files into an ADO.NET DataTable.
If not, however, the TextFieldParser in the Microsoft.VisualBasic.dll assembly (usable from C# too) makes parsing CSV files very simple.
To parse it manually is very simple, and you could have a program that parses it, strips out the first two unnecessary lines and then feeds it directly to SSIS.
Here is a link for using LINQ to read it in:
http://blogs.msdn.com/wriju/archive/2009/05/24/linq-to-csv-getting-data-the-way-you-want.aspx
Using The Built In OLEDB CSV Parser via C# in order to parse a CVS file.
You can find a sample here
It basically lets you treat the csv file like a database table.
The link in Development 4.0's post has dissapeared. The code in that link was the following:
class CSVParser
{
public static DataTable ParseCSV(string path)
{
if (!File.Exists(path))
return null;
string full = Path.GetFullPath(path);
string file = Path.GetFileName(full);
string dir = Path.GetDirectoryName(full);
//create the "database" connection string
string connString = "Provider=Microsoft.Jet.OLEDB.4.0;"
+ "Data Source=\"" + dir + "\\\";"
+ "Extended Properties=\"text;HDR=No;FMT=Delimited\"";
//create the database query
string query = "SELECT * FROM " + file;
//create a DataTable to hold the query results
DataTable dTable = new DataTable();
//create an OleDbDataAdapter to execute the query
OleDbDataAdapter dAdapter = new OleDbDataAdapter(query, connString);
try
{
//fill the DataTable
dAdapter.Fill(dTable);
}
catch (InvalidOperationException /*e*/)
{ }
dAdapter.Dispose();
return dTable;
}
}
}

Categories