External Table not in expected format open xml - c#

I am trying to upload an excel(.xlsx) file in my application which has been created by the same application via open xml sdk. I am facing the exception 'External table not in expected format'. However if i manually open the file and save it and try again, it is uploaded without any errors.
Is there any way to programatically perform the task of opening the excel file and save ? I cannot ask my user/client to follow this workaround. Any leads would be helpful. Below is the code snippet which is throwing the exception. The line 'con.open()' is throwing the mentioned exception. Please find the connection string used
private readonly string connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0 Xml;HDR=Yes;MAXSCANROWS=0;IMEX=1\";";
public DataTable GetSheetData(string sheetName)
{
System.IO.FileInfo fileInfo = new System.IO.FileInfo(this.filePath);
DataTable excelData = new DataTable();
excelData.Locale = CultureInfo.InvariantCulture;
using (OleDbConnection con = new OleDbConnection(string.Format(CultureInfo.CurrentCulture, this.connectionString, this.filePath)))
{
con.Open();
if (!string.IsNullOrEmpty(sheetName))
{
using (OleDbDataAdapter dataAdapter = new OleDbDataAdapter(string.Format(CultureInfo.CurrentCulture, "select * from [{0}$]", sheetName), con))
{
dataAdapter.Fill(excelData);
}
}
}
return excelData;
}

I figured out a workaround by programatically opening the excel file and saving it by Interop. Now I am able to upload the excel file without any errors.
var ExcelApp = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook workbook = ExcelApp.Workbooks.Open(filePath);
workbook.Save();
workbook.Close();
ExcelApp.Quit();

Related

SSIS Excel C# Import Script returns empty table when importing xlsx file saved by other users

I have created a SSIS import task, where in For Each Loop container I have Data Flow Task, in which I have Script Component where I try to import xlsx files from external drive folder to upload to database.
My excel connection method is:
private DataTable QueryData(string FileName, string Header, string QueryString)
{
string connectionString;
OleDbConnection excelConnection;
OleDbDataAdapter dataAdapter;
DataSet excelDataSet;
connectionString = "Provider = Microsoft.ACE.OLEDB.16.0; Data Source ="
+ FileName + ";Extended Properties=\"Excel 12.0 XML;HDR= "
+ Header + ";IMEX=1;\"";
excelConnection = new OleDbConnection(connectionString);
dataAdapter = new OleDbDataAdapter(QueryString, excelConnection);
excelDataSet = new DataSet();
dataAdapter.Fill(excelDataSet, "Sheet1");
excelConnection.Close();
return excelDataSet.Tables["Sheet1"];
}
The Script component works fine with files saved by me.
When the component tries to get information from Excel files that are saved by others, the method returns only one row with empty object[].
I have tried unsuccessfully to Run the SSIS as Administrator and also in the server as I suspect there might be problems with file permissions.

how to read an excel file which has no path

I've been using this code to read an excel file and it works fine when i am trying to read saved excel files
string con = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\temp\test.xls;" + #"Extended Properties='Excel 8.0;HDR=Yes;'";
using(OleDbConnection connection = new OleDbConnection(con))
{
connection.Open();
OleDbCommand command = new OleDbCommand("select * from [Sheet1$]",
connection);
using(OleDbDataReader dr = command.ExecuteReader())
{
while(dr.Read())
{
var row1Col0 = dr[0];
Console.WriteLine(row1Col0);
}
}
}
theres and application which opens an excel file which updates data every second and here is the pic of the app
here you can see the excel file being opened in the taskbar.when i used the process code to read the path of the excel file using this code i get no data as the file located in that path is empty
Process[] processlist = Process.GetProcesses();
foreach (Process theprocess in processlist)
{
if (theprocess.ProcessName == "EXCEL")
{
Console.WriteLine(theprocess.ProcessName, theprocess.Id);
string fullPath = theprocess.MainModule.FileName;
//fullpath = C:\\Program Files (x86)\\Microsoft Office\\Office12\\EXCEL.EXE
}
}
the application might be using the instance of ms excel directly.is there any alternative step to read this excel file by the process id directly instead of the path?
Thanks in advance.
Processes are not meant to be used this way. You can start, stop and kill a Process, but there is no way to gain access to it's memory and read a file (actually, any stream of data) with it. I also don't think that there is a way to access the path of the opened file by the Process class.
However, using the Office Interop COM API, you can get the current file, including it's path with Application.ActiveWorkbook.FullName.
Be advised, that this solution works only if one instance of Excel is opened.
Microsoft.Office.Interop.Excel.Application MyExcelApp = (Microsoft.Office.Interop.Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
string FullPath = MyExceAppl.ActiveWorkbook.FullName;

Excel sheet to SQL table

I get the Excel sheet with data uploaded from UI, I need to access that sheet through WCF service and insert the data contained in it into a SQL table.
Kindly guide how this can be done.
I am facing challenge in reading that Excel sheet through WCF service.
I have used below code to read a Excel sheet from a local drive. Change Source property to your FTP location of your excel sheet.
string con = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\MyData.xlsx;" +
#"Extended Properties='Excel 8.0;HDR=Yes;'";
using (OleDbConnection connection = new OleDbConnection(con))
{
connection.Open();
OleDbCommand command = new OleDbCommand("select * from [Sheet1$]", connection);
using (OleDbDataReader dr = command.ExecuteReader())
{
while (dr.Read())
{
// Do your things here
}
}
}
Note: .xls has data limitations whereas .xlsx supports more data rows in a sheet. You need to install Microsoft Office Access database engine 2007 if you are going to read .xlsx files
string UploadedFilePath = FullPathOfExcelOnTheServer;
string ExcelConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + UploadedFilePath + ";Extended Properties=\"Excel 12.0;HDR=Yes;IMEX=1;FMT=Delimited\"";
using (OleDbConnection oledbConnExcel = new OleDbConnection(ExcelConn))
{
oledbConnExcel.Open();
using (OleDbDataAdapter oledbAdapterExcel = new OleDbDataAdapter("SELECT * from [" + SheetName + "$]", oledbConnExcel))
{
using (DataTable dtblSheetData = new DataTable())
{
try
{
oledbAdapterExcel.Fill(dtblSheetData);
}
catch (Exception lexQuery)
{
}
}
}
oledbConnExcel.Close();
}
Fact is the is no way to read the excel data through WCF Service. But You can cosider this approaches
You may:
Read all excel data on client side and call WCF service and include all data from excel in parameter as (array of strings)?
You can create macro(VB) in Excel sheet and what call WCF Service and send data through parameter. When You have all logic in one place.
If client side is .NET side You can use atribbute [KnowsTypeAtribbute].Then You can call WCF service with param type as Excel type (Sheet or other). May by use some type form OpenXml dll may by usefull (But I don't know is sheet or other types is serializable. A serializable is require)
You can send to WFC service path to file and read excel file from that path through WCF service.

How to determine whether excel workbook is password protected or not in C# using OLEDB?

I am reading an excel file using 'OLEDB'. I need a provision where I can determine whether excel file that I am accessing is password protected or not. Please find my code below:
private DataSet LoadExcel(string fileName, string tableName)
{
string path = fileName;
string connStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=Excel 12.0;";
System.Data.OleDb.OleDbConnection MyConnection;
System.Data.DataSet DtSet;
System.Data.OleDb.OleDbDataAdapter MyCommand;
MyConnection = new System.Data.OleDb.OleDbConnection(connStr);
MyConnection.Open();
DataTable dtExcelSchema;
dtExcelSchema = MyConnection.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, null);
string SheetName = dtExcelSchema.Rows[0]["TABLE_NAME"].ToString();
MyCommand = new System.Data.OleDb.OleDbDataAdapter("select * from [" + SheetName + "]", MyConnection);
MyCommand.TableMappings.Add("Table", tableName);
DtSet = new System.Data.DataSet();
MyCommand.Fill(DtSet);
MyConnection.Close();
return DtSet;
}
My code is breaking up on line "MyConnection.Open();" because the excel file which it is accessing here is password-protected. If I could check that, I will bypass the code and display a user-friendly message. Please help if anyone has any idea on this front.
Thanks in Advance!!
From http://www.connectionstrings.com/excel/
If the Excel workbook is protected by a password, you cannot open it for data access, even by supplying the correct password with your connection string. If you try, you receive the following error message: "Could not decrypt file."
OLEDB connection will not work for password protected worksheets. If there is some exception, you can detect the exact type and catch it.
Other way is to use the Office API and use the HasPassword property.
Workbook book = '.....xyz''';
if (book.HasPassword) { ... }
Have you tried sth like that?
try
{
MyConnection.Open();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Per Aseem's first response, the "Could not decrypt file." problem is a result of the Excel file not being in a trusted location. I had the same problem and solved it by moving the Excel file to a trusted location or adding the folder that the Excel file is in to the Trusted Locations.

xlsx file upload not working correctly - works when file is open but not when closed

I've been doing research on this problem for about a day and a half and haven't found a solution to my problem yet. This is my scenario:
I have a AsyncFileUpload and a button which is configured to accept only xls and xlsx files (Excel) file. This file that is uploaded is used to import information into a gridview. The old format xls files works fine. The problem comes when I want to upload the xlsx file. I've tested multiple scenarios and I have found that it works perfectly when the xlsx file is currectly/actively open. When it is closed it gives me errors. I have fiddled and explored solutions to this problem and the range of errors I have received is quite large. But the most prominent errors where the following:
1. External table is not in the expected format.
2. could-not-find-installable-isam
I have found an article relating to the second error (Could not find installable ISAM) but I haven't tried all the suggested solutions yet because I would rather avoid making changes to the windows registry because I do not have exstensive knowledge regarding this matter.
I'm attaching the code that I use to make the connection between the OleDb and the excel file:
protected void AsyncUpload_UploadedComplete(object sender, AjaxControlToolkit.AsyncFileUploadEventArgs e)
{
string connString = "";
string strFileType = Path.GetExtension(e.FileName).ToLower();
string path = e.FileName;
////Connection String to Excel Workbook
if (strFileType.Trim() == ".xls")
{
connString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + path + ";Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=2\"";
}
else if (strFileType.Trim() == ".xlsx")
{
connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=Excel 12.0;HDR=Yes;IMEX=1";
}
string query = "SELECT * FROM [sheet1$]";
OleDbConnection conn = new OleDbConnection(connString);
if (conn.State == ConnectionState.Closed)
conn.Open();
OleDbCommand cmd = new OleDbCommand(query, conn);
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
using (OleDbDataReader dr = cmd.ExecuteReader())
{
_InsertWrapper.clearLists();
while (dr.Read())
{
var row1Col0 = dr[0];
Console.WriteLine(row1Col0);
_InsertWrapper.GenerateList(dr);
}
}
da.Dispose();
conn.Close();
conn.Dispose();
InventoryGrid.DataBind();
ErrorsGrid.DataBind();
}
If someone has additional knowledge or an explanation that can contribute please add it so that more people that are struggling with the same type of problem can gain as much information from this question as possible.We are all still learning.
So, main idea: Need to find a solution to successfully upload the xlsx file
Try using third party tools. They work efficiently:
http://code.google.com/p/excellibrary/

Categories