Changing upload controller from supporting .xlsx to .csv - c#

I have an MVC application which allows an admin user to upload 2 different excel file onto the system; the controller then creates a dataset with the excel data and then populates either a "Schools" or a "School2" database with the dataset using an SqlBulkCopy.
These uploads work perfect when I test them locally using IIS Express, although the same version deployed to AWS elastic beanstalk throws an error when I press the import button. As far as I am aware, this is due to my AWS RDS needing access to the OleDB provider jet drivers; something which I can not do because these drivers can not just be installed on an AWS RDS like they can be on an EC2 instance.
So my plan is to change my upload controller around to accept .csv files instead of excel files. This should solve my problem and allow my upload buttons to work after being deployed on AWS. Could someone help me/point me in the right direction to change my controller to support .csv instead of excel please?
Upload Controller:
namespace CampBookingSys.Controllers
{
public class UploadController : Controller
{
SqlConnection con = new SqlConnection(#"Data Source=bookingdb.cwln7mwjvxdd.eu-west-1.rds.amazonaws.com,1433;Initial Catalog=modeldb;User ID=craig1990;Password=27Oct90!;Database=modeldb;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False");
OleDbConnection Econ;
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(HttpPostedFileBase file)
{
string filename = Guid.NewGuid() + Path.GetExtension(file.FileName);
string filepath = "/excelfolder/" + filename;
file.SaveAs(Path.Combine(Server.MapPath("/excelfolder"), filename));
InsertExceldata(filepath, filename);
return View();
}
[HttpPost]
public ActionResult Index2(HttpPostedFileBase file)
{
string filename = Guid.NewGuid() + Path.GetExtension(file.FileName);
string filepath = "/excelfolder/" + filename;
file.SaveAs(Path.Combine(Server.MapPath("/excelfolder"), filename));
InsertExceldata2(filepath, filename);
return RedirectToAction("Index");
}
private void ExcelConn(string filepath)
{
string constr = string.Format(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=""Excel 12.0 Xml;HDR=YES;""", filepath);
Econ = new OleDbConnection(constr);
}
private void InsertExceldata(string filepath, string filename)
{
string fullpath = Server.MapPath("/excelfolder/") + filename;
ExcelConn(fullpath);
string query = string.Format("Select * from [{0}]", "Sheet1$");
OleDbCommand Ecom = new OleDbCommand(query, Econ);
Econ.Open();
DataSet ds = new DataSet();
OleDbDataAdapter oda = new OleDbDataAdapter(query, Econ);
Econ.Close();
oda.Fill(ds);
DataTable dt = ds.Tables[0];
SqlBulkCopy objbulk = new SqlBulkCopy(con);
objbulk.DestinationTableName = "dbo.Schools";
objbulk.ColumnMappings.Add("AcademicYear", "AcademicYear");
objbulk.ColumnMappings.Add("RollNumber", "RollNumber");
objbulk.ColumnMappings.Add("OfficialSchoolName", "OfficialSchoolName");
objbulk.ColumnMappings.Add("Address1", "Address1");
objbulk.ColumnMappings.Add("Address2", "Address2");
objbulk.ColumnMappings.Add("Address3", "Address3");
objbulk.ColumnMappings.Add("Address4", "Address4");
objbulk.ColumnMappings.Add("County", "County");
objbulk.ColumnMappings.Add("Eircode", "Eircode");
objbulk.ColumnMappings.Add("LocalAuthority", "LocalAuthority");
objbulk.ColumnMappings.Add("X", "X");
objbulk.ColumnMappings.Add("Y", "Y");
objbulk.ColumnMappings.Add("ITMEast", "ITMEast");
objbulk.ColumnMappings.Add("ITMNorth", "ITMNorth");
objbulk.ColumnMappings.Add("Latitude", "Latitude");
objbulk.ColumnMappings.Add("Longitude", "Longitude");
con.Open();
objbulk.WriteToServer(dt);
con.Close();
}
private void InsertExceldata2(string filepath, string filename)
{
string fullpath = Server.MapPath("/excelfolder/") + filename;
ExcelConn(fullpath);
string query = string.Format("Select * from [{0}]", "Sheet1$");
OleDbCommand Ecom = new OleDbCommand(query, Econ);
Econ.Open();
DataSet ds = new DataSet();
OleDbDataAdapter oda = new OleDbDataAdapter(query, Econ);
Econ.Close();
oda.Fill(ds);
DataTable dt = ds.Tables[0];
SqlBulkCopy objbulk = new SqlBulkCopy(con);
objbulk.DestinationTableName = "dbo.School2";
objbulk.ColumnMappings.Add("RollNumber", "RollNumber");
objbulk.ColumnMappings.Add("OfficialSchoolName", "OfficialSchoolName");
objbulk.ColumnMappings.Add("Address1", "Address1");
objbulk.ColumnMappings.Add("Address2", "Address2");
objbulk.ColumnMappings.Add("Address3", "Address3");
objbulk.ColumnMappings.Add("Address4", "Address4");
objbulk.ColumnMappings.Add("County", "County");
objbulk.ColumnMappings.Add("Eircode", "Eircode");
objbulk.ColumnMappings.Add("PhoneNumber", "PhoneNumber");
objbulk.ColumnMappings.Add("Email", "Email");
objbulk.ColumnMappings.Add("PrincipalName", "PrincipalName");
objbulk.ColumnMappings.Add("DeisSchool", "DeisSchool");
objbulk.ColumnMappings.Add("SchoolGender", "SchoolGender");
objbulk.ColumnMappings.Add("PupilAttendanceType", "PupilAttendanceType");
objbulk.ColumnMappings.Add("IrishClassification", "IrishClassification");
objbulk.ColumnMappings.Add("GaeltachtArea", "GaeltachtArea");
objbulk.ColumnMappings.Add("FeePayingSchool", "FeePayingSchool");
objbulk.ColumnMappings.Add("Religion", "Religion");
objbulk.ColumnMappings.Add("OpenClosedStatus", "OpenClosedStatus");
objbulk.ColumnMappings.Add("TotalGirls", "TotalGirls");
objbulk.ColumnMappings.Add("TotalBoys", "TotalBoys");
objbulk.ColumnMappings.Add("TotalPupils", "TotalPupils");
con.Open();
objbulk.WriteToServer(dt);
con.Close();
}
}
}

My first advice is to do bulk inserts in the DBMS, not in code. Doing them via code is only prone to add addtional issues.
As far as parsing the .xlsx files go, the OleDB driver is propably unessesary. There are a few basic rules for working with office formats:
if you can limit it to the new ones (.xlsx), you can use the OpenXML SDK. Or any of the Wrappers people made around it. Or even just the .ZipArchive and XMLReader classes.
if you need to support the old formats (.xls) too, you got to use the (t)rusty Office COM Interop. This has all the usual issue of COM Interop, and aditionally needs office installed and a Interactive session
for any given Display Technology and Problem, there might be a 3rd option. But those are few and far in between. As we always got the Interop to fall back on, we never developed a complete Office processing class like so many other languages have.
I would put OlebDB in that last category - a rare and very specific solution.
It always advise for using the first option.
And Officer COM Interop should be silently burried, with the old formats being removed from the file format options. Considering this is a WebApplication that will likely run as services, you will not get the nesseary interactive session anyway.
Of course accepting .csv is also an option. And indeed Excel has full .CSV support.

Related

The Microsoft Jet database engine cannot open the file It is already opened exclusively by another user, or you need permission to view its data

Firstly please don't mark it as duplicate I know it's been asked multiple times here but none of the links helped me.
I am trying to access database which is located on shared drive, also both the mdb file and the folder in which it is stored have full access to everyone. I have hosted my application on two different machines.
Below is the code to connect to access DB
OleDbDataAdapter dataAdapter = null;
DataTable dtAttendance = new DataTable();
try
{
string conStr = System.Configuration.ConfigurationManager.ConnectionStrings["AccessDBPath"].ToString();
using (OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Mode= Share Deny None;Data Source= " + conStr))
{
conn.Open();
OleDbCommand cmd = new OleDbCommand(#"Select EmployeeId AS UserId,AttendanceDate , format(Int(Duration/60),'0') AS Duration,format(Duration Mod 60,'0') AS Remain FROM AttendanceLogs
where EmployeeId =" + userid.ToString() + " and Year(AttendanceDate)="+year+" and Month(AttendanceDate)="+month+" order by AttendanceDate desc", conn);
dataAdapter = new OleDbDataAdapter();
dataAdapter.SelectCommand = cmd;
dataAdapter.Fill(dtAttendance);
conn.Close();
}
}
catch(Exception ee)
{}
Only first time when I tested it, it worked properly and thereafter it started throwing above error.

Create excel file from an object

I am looking for a library which would do something like that:
Lib.Configure.Cells(...)
Lib.CreateExcelFileFromMyObject<MyObject>(myObject);
I believe a long ago I come across such library but cant remember it's name.
May be some one can point me to the right direction.
I know two ways to read or write excel files.
As already said you can access excel files through the office interop interface as described here. This method is slow, but you can do almost everything what you can do with the gui of excel.
Use the OleDb database interface. This possibility is much faster than the first one, but its restricted to data. So as far as i know it is not possible to read/write formatting e.g. some background color of a cell. With the following function you will get the entire data of a sheet of an excel file at once:
private DataSet ConnectAndLoad(string filepath, string sheet)
{
DataSet data_set = new DataSet();
OleDbConnection oledbConn = new OleDbConnection(String.Format("Provider=Microsoft.Ace.Oledb.12.0;Data Source={0};Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=1;\"", filepath));
string query = "Select * From [" + sheet + "$]";
try
{
oledbConn.Open();
OleDbCommand oledbCmd = new OleDbCommand(query, oledbConn);
OleDbDataAdapter ole_da = new OleDbDataAdapter(oledbCmd);
ole_da.Fill(data_set);
}
catch (OleDbException ex)
{
// do some error catching
}
finally
{
oledbConn.Close();
}
return data_set;
}
you can use
using Microsoft.Office.Interop
namespace to access the ms products
For that first you need to do is add that reference to your project

Get data from the excel file using c# asp.net

I am trying to load data using following code.
string path = System.IO.Path.GetFullPath(uploadExcelFile.PostedFile.FileName);
string connString = "provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\Rizwan shahid\\Desktop\\DataUpload\\Req.xls;Extended Properties=Excel 12.0;";
OleDbConnection oledbConn = new OleDbConnection(connString);
try
{
oledbConn.Open();
OleDbCommand cmd = new OleDbCommand("SELECT * FROM [Sheet1$]", oledbConn);
OleDbDataAdapter oleda = new OleDbDataAdapter();
oleda.SelectCommand = cmd;
DataSet ds = new DataSet();
oleda.Fill(ds, "Table");
return ds.Tables[0];
}
catch
{
return null;
}
finally
{
oledbConn.Close();
}
It was working on 32Bit operating system but when run this code on 64Bit OS it gives the following error
The Microsoft Access database engine could not find the object 'Sheet1$'. Make sure the object exists and that you spell its name and the path name correctly. If 'Sheet1$' is not a local object, check your network connection or contact the server administrator.
I am running VS in Administrator mode and found many solution like replace Sheet1 with file name or place file in C drive but still getting the same error.
you can download latest version here of Jet
http://www.microsoft.com/en-us/download/search.aspx?q=jet
This works (I start out with a 'dummy' path and then apply the real runtime path):
OleStringBuilder =
new OleDbConnectionStringBuilder(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\MyExcel.xls;Extended Properties='Excel 8.0;HDR=Yes;IMEX=1';");
OleStringBuilder.DataSource = MapPath(#"~\App_Data\MyExcelWorksheet.xls");

C# Open DBF file

I'm having a problem opening a DBF file - I need to open it, read everything and process it. I tried several solutions (ODBC/OLEDB), several connection string, but nothing worked so far.
The problem is, when I execute the SQL command to get everything from the file, nothing gets returned - no rows. What's even more odd, the content of the DBF file being opened get deleted.
See the code I have:
public override bool OpenFile(string fileName, string subFileName = "")
{
OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Path.GetDirectoryName(fileName) + ";Extended Properties=dBASE IV;User ID=;Password=;");
try
{
if (con.State == ConnectionState.Closed) { con.Open(); }
OleDbDataAdapter da = new OleDbDataAdapter("select * from " + Path.GetFileName(fileName), con);
DataSet ds = new DataSet();
da.Fill(ds);
con.Close();
int i = ds.Tables[0].Rows.Count;
return true;
}
catch
{
return false;
}
}
I debugged the code and watched the file being opend in Windows Explorer. When it reached this line:
da.Fill(ds);
the size of the file dropped to only a few Bytes (from hundreds of kB).
My next thought was to make the DBF file read only. That however cause an "unexpected exception from an external driver".
So my question is - what the heck? I'm sure the file is not corrupt, it is a direct export from some DB. (No, I do not have access to that DB). I can also open that file in MS Office no problem.
I cannot share the DBF file - it contains confidential data.
Two things... just because its a .DBF file extension might night mean its a Dbase IV file. It might actually be that of Visual Foxpro. That said, I would look into downloading and installing the Visual Foxpro OleDB driver from Microsoft download. Next, the OleDbConnection is pointing to the path that has the actual tables (you already have that).
The query itself, shouldn't care about the extension, so I would change your call to get just then name via "Path.GetFileNameWithoutExtension"
It might be a combination of the two.
Connection string for VFP provider
"Provider=VFPOLEDB.1;Data Source=" + FullPathToDatabase
This is not the exact answer but it will help you to find the issue.
Try to give an inline connection string and select query to make sure problem is not with building those. Catch the exception and check the details of it.
OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\folder;Extended Properties=dBASE IV;User ID=;Password=;"); // give your path directly
try
{
con.Open();
OleDbDataAdapter da = new OleDbDataAdapter("select * from tblCustomers.DBF", con); // update this query with your table name
DataSet ds = new DataSet();
da.Fill(ds);
con.Close();
int i = ds.Tables[0].Rows.Count;
return true;
}
catch(Exception e)
{
var error = e.ToString();
// check error details
return false;
}

How to read Excel file in c# by connection string?

How to read the excel file and show its data in grid view ? I tried the ODBC provider its working but, it is happening win "Dns=EXCELF", how it will possible with connection sring ? I generate my Excel sheet connection string as :
Provider=MSDASQL.1;Persist Security Info=False;User ID=admin;Data Source=Excel Files;Initial Catalog=D:\Parallelminds\Tryouts\sample.xlsx
Is that wrong ? please guide me. which connection string i have to give there...?
It varies somewhat by version of Excel, but if this is pre-2007, you can find what you need here: http://connectionstrings.com/excel
Otherwise, browse http://connectionstrings.com/. It's there somewhere, I promise :).
public string BuildExcelConnectionString(string Filename, bool FirstRowContainsHeaders){
return string.Format("Provider=Microsoft.Jet.OLEDB.4.0;
Data Source='{0}';Extended Properties=\"Excel 8.0;HDR={1};\"",
Filename.Replace("'", "''"),FirstRowContainsHeaders ? "Yes" : "No");
}
public string BuildExcel2007ConnectionString(string Filename, bool FirstRowContainsHeaders){
return string.Format("Provider=Microsoft.ACE.OLEDB.12.0;
Data Source={0};Extended Properties=\"Excel 12.0;HDR={1}\";",
Filename.Replace("'", "''"),FirstRowContainsHeaders ? "Yes" : "No");
}
private void ReadExcelFile(){
string connStr = BuildExcel2007ConnectionString(#"C:\Data\Spreadsheet.xlsx", true);
string query = #"Select * From [Sheet1$] Where Row = 2";
System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection(connStr);
conn.Open();
System.Data.OleDb.OleDbCommand cmd = new System.Data.OleDb.OleDbCommand(query, conn);
System.Data.OleDb.OleDbDataReader dr = cmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(dr);
dr.Close();
conn.Close();
}
This Excel Data Provider is very handy. I recently used it on one of my client's websites with a few minor customizations. If you look through the code you should be able to get a solid idea of how to query Excel from C#.
Just a warning: if Excel is not installed on the deployment machine then you will be restricted to parsing standard XLS files (Office thru 2003), and will not be able to read XLSX (Office 2007).

Categories

Resources