Excel File Reading External table is not in the expected format - c#

I am generating excel file with JS,then uploading it in a temporary folder then reading it after uploading.Its giving me error " External table is not in the expected format." when I am trying to read the generated Excel file(its in xls fomat,same as with xlsx), If I make excel file in MS Excel and read it,its working fine
This is how I am generating
function GenerateExcel() {
var tab_text = $("#hdnUserData").val();
tab_text = tab_text.replace(/<A[^>]*>|<\/A>/g, ""); //remove if u want links in your table
tab_text = tab_text.replace(/<img[^>]*>/gi, ""); // remove if u want images in your table
tab_text = tab_text.replace(/<input[^>]*>|<\/input>/gi, ""); // reomves input params
var ua = window.navigator.userAgent;
var msie = ua.indexOf("MSIE ");
if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./)) // If Internet Explorer
{
txtArea1.document.open("txt/html", "replace");
txtArea1.document.write(tab_text);
txtArea1.document.close();
txtArea1.focus();
sa=txtArea1.document.execCommand("SaveAs",true,"Users Report.xls");
//sa = txtArea1.document.execCommand('SaveAs', true, 'Error Report.xsl');
}
else//other browser not tested on IE 11
sa = window.open('data:application/vnd.ms-excel,' + encodeURIComponent(tab_text));
return (sa);
}
the excel data in columns like this
UserID Name Username
and hidden field have data in CSV like this
1,Test,test123;2,myuser,muser1
This is how I am reading excel
using (var conn = new OleDbConnection())
{
var dt = new DataTable("dtExcel");
string importFileName = path;//Path of uploaded excel file with filename
string fileExtension = System.IO.Path.GetExtension(importFileName);
if (fileExtension == ".xls")
conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + importFileName + ";" + "Extended Properties='Excel 8.0;HDR=YES;IMEX=1;'";
if (fileExtension == ".xlsx")
conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + importFileName + ";" + "Extended Properties='Excel 12.0 Xml;HDR=YES;IMEX=1;'";
conn.Open();
DataTable dtSheets = conn.GetSchema("Tables");
string firstSheet = dtSheets.Rows[0]["TABLE_NAME"].ToString();
using (var comm = new OleDbCommand())
{
comm.CommandText = "select * from [" + firstSheet + "]";
comm.Connection = conn;
using (var da = new OleDbDataAdapter())
{
da.SelectCommand = comm;
da.Fill(dt);
}
}
}
any alternative approach for reading?I have tried with stream but same error.
Error is appearing at con.Open()

Related

Importation of Master data with standard validation

I had excel file, button (import), openfiledialog and gridview at VB.Net 2013.
My task is to make a button that will extract all data from excel file to datagridview
openFileDialog1.InitialDirectory = "C:\\Users\\ProgrammerPC1\\Desktop\\DLAV FILES";
openFileDialog1.Title = "Import Master Data";
openFileDialog1.FileName = "";
openFileDialog1.Filter = "Excel Files|*.xls;*.xlsx;*.xlsm";
try {
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
string name = "Sheet1";
string constr = #"provider=Microsoft.Jet.OLEDB.4.0;Data Source='" + openFileDialog1.FileName + "'; Extended Properties=Excel 8.0; HDR=Yes; IMEX=1;";
System.Data.OleDb.OleDbConnection con = new System.Data.OleDb.OleDbConnection(constr);
System.Data.OleDb.OleDbCommand oconn = new System.Data.OleDb.OleDbCommand("SELECT * FROM [" + name + "$]", con);
con.Open();
System.Data.OleDb.OleDbDataAdapter adapter = new System.Data.OleDb.OleDbDataAdapter(oconn);
DataTable data = new DataTable();
adapter.Fill(data);
dataGridView1.DataSource = data;
}
else
{
MessageBox.Show("Operation Cancelled");
}
}catch (Exception err)
{
MessageBox.Show(err.Message);
}
My Error is
external table is not in the expected format
I found that you're using same connection string provider (MS Jet OLEDB 4.0 Provider) for both XLS (for Excel 97-2003) and XLSX (for Excel 2007 & above) files, hence causing external table is not in the expected format error when trying to read XLSX/XLSM files.
You need to use 2 separate connection string and switch them based from file extension stored in OpenFileDialog with Path.GetExtension() method as in given example below:
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
string extension = Path.GetExtension(openFileDialog1.FileName); // get file extension
string name = "Sheet1"
using (System.Data.OleDb.OleDbConnection con = new System.Data.OleDb.OleDbConnection())
{
switch (extension)
{
case ".xls": // Excel 97-2003 files
// Excel 97-2003 connection string
string xlsconstr = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source='" + openFileDialog1.FileName + "'; Extended Properties=Excel 8.0; HDR=Yes; IMEX=1;";
con.ConnectionString = xlsconstr;
break;
case ".xlsx": // Excel 2007 files
case ".xlsm":
// Excel 2007+ connection string, see in https://www.connectionstrings.com/ace-oledb-12-0/
string xlsxconstr = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source='" + openFileDialog1.FileName + "'; Extended Properties=Excel 12.0; HDR=Yes; IMEX=1;";
con.ConnectionString = xlsxconstr;
break;
}
using (System.Data.OleDb.OleDbCommand oconn = new System.Data.OleDb.OleDbCommand("SELECT * FROM [" + name + "$]", con))
{
con.Open();
System.Data.OleDb.OleDbDataAdapter adapter = new System.Data.OleDb.OleDbDataAdapter(oconn);
DataTable data = new DataTable();
adapter.Fill(data);
dataGridView1.DataSource = data;
}
}
}
else
{
MessageBox.Show("Operation Cancelled");
}

Arabic letter data save to database as "?"

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

Reading Excel file with OleDB returns UPC numbers in wrong format

I have to read an Excel file with OleDB in a web application and save the data in a Database.
Accessing the file and reading it with DataAdapter or OleDbDataReader works. I needed to specify IMEX=1 and TypeGuessRows=0 because the data in the file has headers that I need to parse, but they are not on the first row. So basically, I need to read the lines until I hit a known header and then start parsing all the data after it.
In the first column there are UPC numbers with values like this: 5053366261702
But even though the fields are read as text, the OleDbDataReader returns the numbers in a scientific way like this: 5.05337E+12
If I don't read the lines as text, the numbers are returned correctly but the header will disappear.
I added the important part of the code. Thanks in advance for any help.
string conn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='" + fileName + "';Extended Properties='Excel 12.0;HDR=No;IMEX=1;ImportMixedTypes=Text;TypeGuessRows=0'";
using (OleDbConnection objConn = new OleDbConnection(conn))
{
objConn.Open();
var exceltables = objConn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, new Object[] { null, null, null, "TABLE" });
var tablename = exceltables.Rows[0]["TABLE_NAME"];
using (OleDbCommand objCmdSelect = new OleDbCommand("SELECT * FROM [" + tablename + "]", objConn))
{
using (OleDbDataReader reader = objCmdSelect.ExecuteReader())
{
while (reader.Read())
{
string abc = reader[0].ToString(); //do some parsing
}
}
}
}
I found a solution that works for me. I open the file with two different connection strings now.
Provider=Microsoft.ACE.OLEDB.12.0;Data Source='filename.xlsx';Extended Properties='Excel 12.0;HDR=No;IMEX=1;ImportMixedTypes=Text;TypeGuessRows=0'
First one to get the headers and when I found them I save the line number and open the file again with IMEX=0.
Provider=Microsoft.ACE.OLEDB.12.0;Data Source='filename.xlsx';Extended Properties='Excel 12.0;HDR=No;IMEX=0;ImportMixedTypes=Text;TypeGuessRows=0'
string connHeaders = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='" + fileName + "';Extended Properties='Excel 12.0;HDR=No;IMEX=1;ImportMixedTypes=Text;TypeGuessRows=0'";
string connData = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='" + fileName + "';Extended Properties='Excel 12.0;HDR=No;IMEX=0;ImportMixedTypes=Text;TypeGuessRows=0'";
int dataStartRow = 0;
string tablename = "";
#region Open file to find headers
using (OleDbConnection objConn = new OleDbConnection(connHeaders))
{
objConn.Open();
var exceltables = objConn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, new Object[] { null, null, null, "TABLE" });
tablename = exceltables.Rows[0]["TABLE_NAME"].ToString();
using (OleDbCommand objCmdSelect = new OleDbCommand("SELECT * FROM [" + tablename + "] ", objConn))
{
using (OleDbDataReader reader = objCmdSelect.ExecuteReader())
{
while (reader.Read())
{
if (reader[0].ToString().ToLower() == "upc")
{
for (int i = 0; i < reader.FieldCount; i++)
{
//find all necessary headers
}
break;
}
dataStartRow++;
}
}
}
}
#endregion
#region Open file again to read data
using (OleDbConnection objConn = new OleDbConnection(connData))
{
objConn.Open();
using (OleDbCommand objCmdSelect = new OleDbCommand("SELECT * FROM [" + tablename + "] ", objConn))
{
using (OleDbDataReader reader = objCmdSelect.ExecuteReader())
{
for (int i = 0; i < dataStartRow; i++) reader.Read();
while (reader.Read())
{
//read the line to save it in Database
}
}
}
}
I have a simple answer that works for me.
File.WriteAllText(file, Regex.Replace( File.ReadAllText(file), "(?<=,)([0-9]{12,})(?=,)", "\"$1\""));
This works because it puts double quotes around any field with 12 or more digits which is when the scientific notation comes in.

How to fetch a excel file from a folder?

I'm having a excel file in a folder. but i dont know to fetch that file from the folder.
but I'm checking whether the file exists.
here is my code:
protected void Page_Load(object sender, EventArgs e)
{
string filePath = Server.MapPath("~/Upload/Sample.xlsx");
bool fileexists = File.Exists(filePath); //Here fileexists = true
}
I need to save that excel file in sql database.
I need to save the fileName(varchar(256)),Data(varbinary(max)),Path(varchar(256)) of that excel file into sql database.
please help me out
Try this to get and read an xlsx file .
if (Directory.Exists(Server.MapPath("path")))
{
string filename = Path.GetFileName("path");// to get filename
string conStr = string.Empty;
string extension = Path.GetExtension(filename);// get extension
if (extension == ".xls" || extension == ".xlsx")
{
switch (extension)
{
case ".xls": //Excel 1997-2003
conStr = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source='" + mappingPath + "';" + "Extended Properties=Excel 8.0;";
break;
case ".xlsx": //Excel 2007
conStr = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source='" + mappingPath + "';" + "Extended Properties=Excel 8.0;";
break;
default:
break;
}
OleDbConnection connExcel = new OleDbConnection(conStr.ToString());
OleDbCommand cmdExcel = new OleDbCommand();
OleDbDataAdapter oda = new OleDbDataAdapter();
connExcel.Open();
DataTable dtExcelSchema;
dtExcelSchema = connExcel.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
string SheetName = dtExcelSchema.Rows[0]["TABLE_NAME"].ToString();
ViewState["SheetName"] = SheetName;
//Selecting Values from the first sheet
//Sheet name must be as Sheet1
OleDbDataAdapter da = new OleDbDataAdapter("SELECT * From [" + SheetName + "]", conStr.ToString()); // to fetch data from excel
da.Fill(dtExcel);
}
This is much simpler than you think, it should be something like:
if (File.Exists(filePath)) {
byte[] data = File.ReadAllBytes(filePath);
string fileName = Path.GetFileName(filePath);
const string query = "INSERT INTO Files (FileName, Data, Path) VALUES (#FileName, #Data, #Path)";
using (var connection = new SqlConnection(connectionString))
using (var command = new SqlCommand(query, connection)) {
command.Parameters.AddWithValue("#FileName", fileName);
command.Parameters.AddWithValue("#Data", data);
command.Parameters.AddWithValue("#Path", filePath);
connection.Open();
command.ExecuteNonQuery();
}
}

data import from excel facing an issue

I am importing data from MS Excel.
The code i have written is,
var ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" +
uploadfile.PostedFile.FileName + ";" + "Extended Properties=Excel 12.0;";
OleDbConnection objConn = new OleDbConnection(sConnectionString);
objConn.Open();
try
{
var objCmdSelect = new OleDbCommand("select * from [Sheet1$]", objConn);
}
and so on.
I got an error which looks very generic to me
The Microsoft Office 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
*
My worksheet name is spelled correclty
but for my confirmation, i did below code
dt = objConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
if(dt == null)
{
return null;
}
var 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++;
}
*
but i got my Data Table null.
My question is the connection is open successfully but i can't read data from the excel file.
Is there any special Authentication required.?
because i am getting the above error.
Instead if Ace.OLEDB you may try by Microsoft.Jet.OLEDB, because I faced the simillar then I switch over to Jet.OLEDB
string MyExelFile = "C:\Temp\Sample.xls";
string MyExcelSheet = "[Sheet1$]";
string StrConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + MyExelFile + ";
Extended Properties=\"Excel 8.0; HDR=Yes; IMEX=1\"";
String MySQLSelect = "select * from " + MyExcelSheet + "";
DataTable Items=new DataTable() ;
System.Data.OleDb.OleDbConnection Cn = new System.Data.OleDb.OleDbConnection();
Cn.ConnectionString = StrConn;
System.Data.OleDb.OleDbDataAdapter Da = new System.Data.OleDb.OleDbDataAdapter
(MySQLSelect, Cn);
Cn.Open();
Da.Fill(Items);
Cn.Close();
</pre>

Categories