I had created an asp.net mvc4 application and I deployed it to the web.
In this application I have a controller to import some Excel file into the database.
On my localhost it's working fine, but on the server when I try to import a file that has the same name as an existing file it gives me an error
(I can't see the exception I see just some nice message (catch .....)
This is a part of code :
if (Request.Files["file"].ContentLength > 0)
{
string fileExtension = System.IO.Path.GetExtension(Request.Files["file"].FileName);
if (fileExtension == ".xls" || fileExtension == ".xlsx")
{
string fileLocation = Server.MapPath("~/Content/") + Request.Files["file"].FileName;
if (System.IO.File.Exists(fileLocation))
{
System.IO.File.Delete(fileLocation);
}
Request.Files["file"].SaveAs(fileLocation);
string excelConnectionString = string.Empty;
excelConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" +
fileLocation + ";Extended Properties=\"Excel 12.0;HDR=Yes;IMEX=2\"";
//connection String for xls file format.
if (fileExtension == ".xls")
{
excelConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +
fileLocation + ";Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=2\"";
}
//connection String for xlsx file format.
else if (fileExtension == ".xlsx")
{
excelConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" +
fileLocation + ";Extended Properties=\"Excel 12.0;HDR=Yes;IMEX=2\"";
}
//Create Connection to Excel work book and add oledb namespace
OleDbConnection excelConnection = new OleDbConnection(excelConnectionString);
excelConnection.Open();
DataTable dt = new DataTable();
dt = excelConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
if (dt == null)
{
return null;
}
String[] excelSheets = new String[dt.Rows.Count];
int t = 0;
//excel data saves in temp file here.
foreach (DataRow row in dt.Rows)
{
excelSheets[t] = row["TABLE_NAME"].ToString();
t++;
}
OleDbConnection excelConnection1 = new OleDbConnection(excelConnectionString);
string query = string.Format("Select * from [{0}]", excelSheets[0]);
using (OleDbDataAdapter dataAdapter = new OleDbDataAdapter(query, excelConnection1))
{
dataAdapter.Fill(ds);
}
excelConnection.Close();
}
if (fileExtension.ToString().ToLower().Equals(".xml"))
{
string fileLocation = Server.MapPath("~/Content/") + Request.Files["FileUpload"].FileName;
if (System.IO.File.Exists(fileLocation))
{
System.IO.File.Delete(fileLocation);
}
Request.Files["FileUpload"].SaveAs(fileLocation);
XmlTextReader xmlreader = new XmlTextReader(fileLocation);
ds.ReadXml(xmlreader);
xmlreader.Close();
}
}
My answer comes without knowledge of the specific exception (as you mentioned, you can't see the exception yourself). In my similar experience, I've run across the same problem, and it was resolved by installing the Microsoft ACE OLEDB 12.0 driver on the server. I've installed the following component to resolve the problem:
2007 Office System Driver - Data Connectivity Components:
http://www.microsoft.com/en-us/download/details.aspx?id=23734
If that doesn't help, more information regarding the exception you're seeing would be helpful in solving the problem.
Related
I wanna read data from excel spreadsheet and insert them into Access data base(.accdb). there is a problem with data format in excel. some cells are in incorrect type. Correct format for example is 99999 and incorrect is 9999-888 . because of dash(-) ole data adapter return null values instead of text. how should i get whole cell block?
I have tried change the cell format of excel from General to Text but the problem is still available.
thanks
string connectionStringExcel = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + openFileDialog1.FileName + ";Extended Properties=Excel 12.0;";
using (OleDbConnection connectionExcel = new OleDbConnection(connectionStringExcel))
{
OleDbDataAdapter daExcel = new OleDbDataAdapter(#"SELECT * FROM [priclist$]", connectionExcel);
DataTable dtExcel = new DataTable();
daExcel.Fill(dtExcel);
dataGridView1.DataSource = dtExcel;
}
By default, the Microsoft.ACE.OLEDB.12.0 provider tries to determine variable type for each column, and assumes the majority type is the column type.
You can override this behaviour by specifying IMEX=1 in the connection string, which uses text when encountering mixed-field types instead of setting the ones not matching the type to Null. Then you can handle the values in your C# code:
string connectionStringExcel = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + openFileDialog1.FileName + ";Extended Properties=Excel 12.0;IMEX=1;";
Read more about the IMEX property by following the link in the comment below
I use the following code to transfer data from Excel to datagrid :
private void btnreadExcell_MouseDown(object sender, MouseButtonEventArgs e)
{
try
{
string filePath = string.Empty;
string fileExt = string.Empty;
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "Excel Files|*.xls;*.xlsx;*.xlsm";
Nullable<bool> result = ofd.ShowDialog();
if (result == true)//if there is a file choosen by the user
{
filePath = ofd.FileName;//get the path of the file
try
{
DataTable dtExcel = new DataTable();
dtExcel = ReadExcel(filePath, fileExt);//read excel file
// dataGrid.Visible = true;
dataGrid.ItemsSource = dtExcel.DefaultView;
datagridheader();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
}
con.Close();
}
catch { MessageBox.Show("error");}
}
public DataTable ReadExcel(string fileName, string fileExt)
{
DataTable dtexcel = new DataTable();
try
{
string conn = string.Empty;
if (fileExt.CompareTo(".xls") == 0)//compare the extension of the file
conn = #"provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + fileName + ";Extended Properties='Excel 8.0;HRD=Yes;IMEX=1';";//for below excel 2007
else
conn = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileName + ";Extended Properties='Excel 12.0;HDR=Yes;IMEX=1';";//for above excel 2007
using (OleDbConnection con = new OleDbConnection(conn))
{
try
{
OleDbDataAdapter oleAdpt = new OleDbDataAdapter("select * from [Sheet1$]", con);//here we read data from sheet1
oleAdpt.Fill(dtexcel);//fill excel data into dataTable
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
}
conn.Clone();
}
catch { MessageBox.Show("error"); }
return dtexcel;
}
My error has been Solved!!! with set both IMEX=1 And HDR=No. if you have changed your header in excel files(first row) use below code to solve same problem as i asked above.
try this
(two connection string have same meaning)
string connectionStringExcel = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + openFileDialog1.FileName + ";Extended Properties='Excel 12.0;HDR=No;IMEX=1';"
Or
string connectionStringExcel = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" +"T13970524.xlsx" + ";Extended Properties=\"Excel 12.0 Xml;HDR=No;IMEX=1\";";
I am developing a program to import excel spreadsheets with C # language, using the OLEDB component, when importing a spreadsheet with 100547 rows the program can only read 54046.
Follows the source code:
public class ReadExcel
{
public string ConnectionExcel(ExcelUpload excelUpload)
{
//connection String for xls file format.
if (excelUpload.fileExtension == ".xls")
{
excelUpload.excelConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + excelUpload.fileLocation + ";Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=2\"";
}
//connection String for xlsx file format.
else if (excelUpload.fileExtension == ".xlsx")
{
excelUpload.excelConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + excelUpload.fileLocation + ";Extended Properties=\"Excel 12.0;HDR=Yes;IMEX=2\"";
}else
{
excelUpload.excelConnectionString = "";
}
return excelUpload.excelConnectionString;
}
public DataTable readArqExcel(string excelConnectionString, DataSet ds)
{
//Create Connection to Excel work book and add oledb namespace
OleDbConnection excelConnection = new OleDbConnection(excelConnectionString);
excelConnection.Open();
DataTable dt = new DataTable();
dt = excelConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
if (dt == null)
{
return null;
}
//Numero de planilhas contidas no excel
String[] excelSheets = new String[dt.Rows.Count];
int count = 0;
//excel data saves in temp file here.
foreach (DataRow row in dt.Rows)
{
excelSheets[count] = row["TABLE_NAME"].ToString();
count++;
}
OleDbConnection excelConnection1 = new OleDbConnection(excelConnectionString);
string query = string.Format("Select * from [{0}]", excelSheets[0]);
using (OleDbDataAdapter dataAdapter = new OleDbDataAdapter(query, excelConnection1))
{
dataAdapter.Fill(ds);
}
excelConnection.Close();
return ds.Tables[0];
}
I have tested IIS 8 (REMOTE SERVER) and IIS Express (Visual Studio local server), I noticed that on the IIS Express server the code works perfectly, but in IIS 8 the code ends up reading the file in half.
Is it some kind of web server configuration?
problem resolved, i altered string of connection OLEBD with MsExcel.
Alter parameter IMEX = 2 for IMEX = 1, as below
if (excelUpload.fileExtension == ".xls")
{
excelUpload.excelConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + excelUpload.fileLocation + ";Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=1\"";
}
//connection String for xlsx file format.
else if (excelUpload.fileExtension == ".xlsx")
{
excelUpload.excelConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + excelUpload.fileLocation + ";Extended Properties=\"Excel 12.0;HDR=Yes;IMEX=1\"";
}
I'm uploading data to DB table using excel sheet
I'm uploading data to ProductStatisticsTemp table
In that table I have following columns
Product_ID
ProductNameEn
ProductNameAr
this the upload data POST method
[HttpPost]
public ActionResult FileUpload(HttpPostedFileBase file)
{
if (Request.Files["file"].ContentLength > 0)
{
string fileExtension = System.IO.Path.GetExtension(Request.Files["file"].FileName);
if (fileExtension == ".xls" || fileExtension == ".xlsx")
{
string fileLocation = Server.MapPath("~/Content/ExcelFiles/") + Request.Files["file"].FileName;
if (System.IO.File.Exists(fileLocation))
{
System.IO.File.Delete(fileLocation);
}
Request.Files["file"].SaveAs(fileLocation);
string excelConnectionString = string.Empty;
excelConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileLocation + ";Extended Properties=\"Excel 12.0;HDR=Yes;IMEX=2\"";
//connection String for xls file format.
if (fileExtension == ".xls")
{
excelConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + fileLocation + ";Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=2\"";
}
//connection String for xlsx file format.
else if (fileExtension == ".xlsx")
{
excelConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileLocation + ";Extended Properties=\"Excel 12.0;HDR=Yes;IMEX=2\"";
}
//Create Connection to Excel work book and add oledb namespace
OleDbConnection excelConnection = new OleDbConnection(excelConnectionString);
excelConnection.Open();
DataTable dt = new DataTable();
dt = excelConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
if (dt == null)
{
return null;
}
String[] excelSheets = new String[dt.Rows.Count];
int t = 0;
//excel data saves in temp file here.
foreach (DataRow row in dt.Rows)
{
excelSheets[t] = row["TABLE_NAME"].ToString();
t++;
}
OleDbConnection excelConnection1 = new OleDbConnection(excelConnectionString);
string query = string.Format("Select * from [{0}]", excelSheets[0]);
using (OleDbDataAdapter dataAdapter = new OleDbDataAdapter(query, excelConnection1))
{
dataAdapter.Fill(ds);
}
}
if (fileExtension.ToString().ToLower().Equals(".xml"))
{
string fileLocation = Server.MapPath("~/Content/ExcelFiles") + Request.Files["FileUpload"].FileName;
if (System.IO.File.Exists(fileLocation))
{
System.IO.File.Delete(fileLocation);
}
Request.Files["FileUpload"].SaveAs(fileLocation);
XmlTextReader xmlreader = new XmlTextReader(fileLocation);
// DataSet ds = new DataSet();
ds.ReadXml(xmlreader);
xmlreader.Close();
}
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
string conn = ConfigurationManager.ConnectionStrings["dbconnection"].ConnectionString;
SqlConnection con = new SqlConnection(conn);
string query = "Insert into ProductStatisticsTemp(Product_ID,ProductNameEn,ProductNameAr) Values('" + ds.Tables[0].Rows[i][0] + "','" + ds.Tables[0].Rows[i][1] + "','" + ds.Tables[0].Rows[i][2] )";
con.Open();
SqlCommand cmd = new SqlCommand(query, con);
cmd.ExecuteNonQuery();
con.Close();
}
}
return RedirectToAction("FileUpload", "FileUpload");
}
But in here data saving smoothly , but ProductNameAr fields Arabic letters values save as "?"
ex: If excel value حساب التوفير للاستثمار Albrka
then its saving in database table as ???? ??????? ????????? Albrka
How to save as exact format in the excel sheet
ps. this ProductNameAr data type in Database table is NVARCHAR
You use non-Unicode string literals 'value' when you should use Unicode literals in the form N'value'
You better rewrite as parameterized SqlCommand passing the values using AddWithValue
string query = "Insert into ProductStatisticsTemp(Product_ID,ProductNameEn,ProductNameAr) Values(#Product_ID,#ProductNameEn,#ProductNameAr)";
SqlCommand cmd = new SqlCommand(query, con);
cmd.Parameters.AddWithValue("#Product_ID", ds.Tables[0].Rows[i][0]);
...etc...
You don't need to re-create and open the SqlConnection inside the loop
In this snippet of code - I get the uploaded file from the user and save it in a folder in my app and then make OleDbConmnection to this Excel File and read the data. My question is - can someone suggest a way which is preferred of reading this excel file but without saving it previously and again as it's in my case fill the datatable with the data
if (Request != null)
{
HttpPostedFileBase file = Request.Files[0];
if ((file != null) && (file.ContentLength > 0) && !string.IsNullOrEmpty(file.FileName))
{
string fileName = file.FileName;
string fileContentType = file.ContentType;
string fileExtension = System.IO.Path.GetExtension(Request.Files[0].FileName);
if (fileExtension == ".xls" || fileExtension == ".xlsx")
{
string fileLocation = Server.MapPath("~/Content/") + Request.Files[0].FileName;
if (System.IO.File.Exists(fileLocation))
{
System.IO.File.Delete(fileLocation);
}
Request.Files[0].SaveAs(fileLocation);
string excelConnectionString = string.Empty;
excelConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" +
fileLocation + ";Extended Properties=\"Excel 12.0;HDR=Yes;IMEX=2\"";
//connection String for xls file format.
if (fileExtension == ".xls")
{
excelConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +
fileLocation + ";Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=2\"";
}
//connection String for xlsx file format.
else if (fileExtension == ".xlsx")
{
excelConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" +
fileLocation + ";Extended Properties=\"Excel 12.0;HDR=Yes;IMEX=2\"";
}
//Create Connection to Excel work book and add oledb namespace
OleDbConnection excelConnection = new OleDbConnection(excelConnectionString);
excelConnection.Open();
OleDbCommand cmd = new OleDbCommand("SELECT * FROM [Sheet1$]", excelConnection);
OleDbDataAdapter objAdapter1 = new OleDbDataAdapter(cmd);
DataTable dt = new DataTable();
DataSet ds = new DataSet();
objAdapter1.Fill(ds);
DataTable Dt = ds.Tables[0];
See this library.
Excel Data Reader
EDIT
example:
if (Request != null)
{
HttpPostedFileBase file = Request.Files[0];
if ((file != null) && (file.ContentLength > 0) && !string.IsNullOrEmpty(file.FileName))
{
string fileName = file.FileName;
string fileContentType = file.ContentType;
string fileExtension = System.IO.Path.GetExtension(Request.Files[0].FileName);
if (fileExtension == ".xls" || fileExtension == ".xlsx")
{
IExcelDataReader excelReader;
if (fileExtension == ".xls")
excelReader = ExcelReaderFactory.CreateBinaryReader(stream);
else
excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
excelReader.IsFirstRowAsColumnNames = true;
DataSet ds = excelReader.AsDataSet();
DataTable Dt = ds.Tables[0];
This line
HttpPostedFileBase file = Request.Files[0];
Say that can't possible convert HttpPostedFile to HttpPostedFileBase
GetExcelSheetNames:
static String[] GetExcelSheetNames(string excelFile, string extention)
{
OleDbConnection objConn = null;
System.Data.DataTable dt = null;
string filepath= excelFile;// +; excelFile;
string Conn = "";
if (extention == "xls")
Conn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filepath+ ";Extended Properties=Excel 8.0;";
else Conn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filepath+ ";Extended Properties=Excel 12.0";
try
{
// Connection String. Change the excel file to the file you
// will search.
// Create connection object by using the preceding connection string.
objConn = new OleDbConnection(Conn);
// Open connection with the database.
objConn.Open();
// Get the data table containg the schema guid.
dt = objConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
if (dt == null)
{
return null;
}
String[] excelSheets = new String[dt.Rows.Count];
int i = 0;
// Add the sheet name to the string array.
foreach (DataRow row in dt.Rows)
{
excelSheets[i] = row["TABLE_NAME"].ToString();
i++;
}
return excelSheets;
}
catch (Exception ex)
{
return null;
}
finally
{
// Clean up.
if (objConn != null)
{
objConn.Close();
objConn.Dispose();
}
if (dt != null)
{
dt.Dispose();
}
}
}
GetTable:
private DataSet GetTable(string filepath, string extention)
{
string strConn;
if (extention == "xls")
{
strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filepath + ";Extended Properties=Excel 8.0;";
}
else
{
strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filepath + ";Extended Properties=Excel 12.0";
}
DataSet myDataSet = new DataSet();
OleDbDataAdapter myCommand = new OleDbDataAdapter("SELECT * FROM [" + GetExcelSheetNames(filepath, extention)[0] + "]", strConn);
myCommand.Fill(myDataSet, "ExcelInfo");
if (myDataSet.Tables[0].Rows.Count > 0)
{
return myDataSet;
}
else return null;
}
I export excel data to datatable by using OleDbDataAdapter.
My both method (above side) works however last row is missing .
Where i miss exactly how can i get all rows from excel ?
Any help will be appreciated.
Thanks.