I run this code two times from the same Excel file, and it works fine, and I'm getting the right table. But when I try to run it a third time it crashes and throws external table is not in the expected format.
Filename = filename;
if (ExcelSet == null)
{
string HDR = firstRowContainsColumnNames ? "Yes" : "No";
string strConn;
if (filename.Substring(filename.LastIndexOf('.')).ToLower() == ".xlsx")
{
strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + Filename + ";Extended Properties=\"Excel 12.0;HDR=" + HDR + ";IMEX=1\"";
}
else if (filename.Substring(filename.LastIndexOf('.')).ToLower() == ".xls")
{
strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Filename + ";Extended Properties=\"Excel 8.0;HDR=" + HDR + ";IMEX=1\"";
}
else
{
throw new Exception("File is not an Excel file");
}
DataSet ds = new DataSet();
using (OleDbConnection conn = new OleDbConnection(strConn))
{
if (conn.State != ConnectionState.Open)
{
conn.Open();
}
DataTable schemaTable = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
foreach (DataRow schemaRow in schemaTable.Rows)
{
string sheet = schemaRow["TABLE_NAME"].ToString();
if (!sheet.EndsWith("_"))
{
try
{
OleDbCommand cmd = new OleDbCommand("SELECT * FROM [" + sheet + "]", conn);
cmd.CommandType = CommandType.Text;
DataTable outputTable = new DataTable(sheet);
ds.Tables.Add(outputTable);
new OleDbDataAdapter(cmd).Fill(outputTable);
outputTable.Dispose();
}
catch (Exception ex)
{
throw new Exception(ex.Message + string.Format("Sheet: {0}.File.F{1}", sheet, Filename), ex);
}
}
}
conn.Close();
conn.Dispose();
}
ExcelSet = ds;
}
I have no clue why it crahes, anyone having the same problem?
Related
I have a situation please help me out. I have to create multiple sheet in one excel file with different queries. Like i have to check if the particular column is null then the record against this query should be in excel file in new sheet and i have to check another column with other name if it is null or empty and then create a sheet for it and sheet should be created only if the query returns some result otherwise there should not be any empty sheet. i have 8 different columns to check .
For Example I have to execute following query which will be in source
SELECT DISTINCT AgencySourceSystemCode,SourceAgencyID,ProgramCode,PolicyNumber,EffectiveDate,AgencyName
FROM POL.vw_PolicyPremiumData
WHERE AgencyName IS NULL OR AgencyName = ''
And Sample result is
AgencySourceSystemCode SourceAgencyID
ProgramCode PolicyNumber
EffectiveDate AgencyName
GEN 1050- CAB DN17000008
2010-06-10 NULL
GEN 1050- CAB DN17000008
2011-06-10 NULL
GEN 1050- CAB DN17000008
2012-06-10 NULL
GEN 1050- CAB DN17000010
2010-06-10 NULL
GEN 1050- CAB DN17000010
2012-06-10 NULL
GEN 1050- CAB DN17000012
2010-06-22 NULL
GEN 1050- CAB DN17000012
2011-06-22 NULL
Here Agency Name is NULL like this i will have source query where Effective can be null .
I used this code snippet to create dynamic Excel file sheets .
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
using System.IO;
using System.Data.OleDb;
using System.Data.SqlClient;
namespace ST_db9b6187d17c4dc99314d6ccb6ee7b08
{
[Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
string query = string.Empty;
string FileName = string.Empty;
string TableName = string.Empty;
string connstring = string.Empty;
string FolderPath = string.Empty;
string where = string.Empty;
string PackageName = "Error";
int SourceId = 0;
int BatchId = 0;
int flag = 0;
public void Main()
{
string datetime = DateTime.Now.ToString("yyyyMMddHHmmss");
try
{
FolderPath = Dts.Variables["$Package::TempFolderPath"].Value.ToString();
FolderPath = FolderPath+"\\";
//if (FolderPath.LastIndexOf("\\")="\\")
//{
// FolderPath = Dts.Variables["$Package::TempFolderPath"].Value.ToString();
//}
if (File.Exists(FolderPath + PackageName + "File.XLSX"))
{
File.Delete(FolderPath + PackageName + "File.XLSX");
}
if (FolderPath.Contains(".xlsx"))
{
FolderPath = FolderPath.Trim('\\');
FolderPath = FolderPath.Remove(FolderPath.LastIndexOf('\\') + 1);
}
//USE ADO.NET Connection from SSIS Package to get data from table
string con = Dts.Connections["oledb_conn"].ConnectionString.ToString();
OleDbConnection _connection = new OleDbConnection(con);
OleDbCommand cmd = new OleDbCommand();
//Read distinct error euerries
query = "select distinct ErrorQuery, SheetName from ErrorMapping where FileType = 'PremiumFile'";
cmd.CommandType = CommandType.Text;
cmd.CommandTimeout = 0;
cmd.CommandText = query;
cmd.Connection = _connection;
_connection.Open();
DataTable dt_ErrorMapping = new DataTable();
dt_ErrorMapping.Load(cmd.ExecuteReader());
_connection.Close();
if (dt_ErrorMapping != null && dt_ErrorMapping.Rows.Count > 0)
{
foreach (DataRow dt_ErrorMapping_row in dt_ErrorMapping.Rows)
{
query = dt_ErrorMapping_row["ErrorQuery"].ToString();
cmd.CommandType = CommandType.Text;
cmd.CommandText = query;
cmd.CommandTimeout = 0;
cmd.Connection = _connection;
_connection.Open();
DataTable dt_ErrorInfo = new DataTable();
dt_ErrorInfo.Load(cmd.ExecuteReader());
_connection.Close();
if (dt_ErrorInfo != null && dt_ErrorInfo.Rows.Count > 0)
{
Error(dt_ErrorMapping_row["SheetName"].ToString());
}
}
}
Dts.TaskResult = (int)ScriptResults.Success;
}
catch (Exception exception)
{
using (StreamWriter sw = File.CreateText(Dts.Variables["$Package::TempFolderPath"].Value.ToString() + "\\" +
"Error" + datetime + ".log"))
{
sw.WriteLine("Error Message: " + exception.Message.ToString());
Dts.TaskResult = (int)ScriptResults.Failure;
}
}
}
public void ExportExcelFile(DataSet ds, string connstring, string SheetName)
{
OleDbConnection Excel_OLE_Con = new OleDbConnection();
OleDbCommand Excel_OLE_Cmd = new OleDbCommand();
//Get Header Columns
string TableColumns = "";
// Get the Column List from Data Table so can create Excel Sheet with Header
foreach (DataTable table in ds.Tables)
{
foreach (DataColumn column in table.Columns)
{
TableColumns += column + "],[";
}
}
// Replace most right comma from Columnlist
TableColumns = ("[" + TableColumns.Replace(",", " Text,").TrimEnd(','));
TableColumns = TableColumns.Remove(TableColumns.Length - 2);
//Use OLE DB Connection and Create Excel Sheet
Excel_OLE_Con.ConnectionString = connstring;
Excel_OLE_Cmd.CommandTimeout = 0;
Excel_OLE_Con.Open();
Excel_OLE_Cmd.Connection = Excel_OLE_Con;
Excel_OLE_Cmd.CommandText = "Create table [" + SheetName + "] (" + TableColumns + ")";
Excel_OLE_Cmd.ExecuteNonQuery();
Excel_OLE_Con.Close();
//Write Data to Excel Sheet from DataTable dynamically
foreach (DataTable table in ds.Tables)
{
bool firstRow = true;
String sqlCommandInsert = "";
String sqlCommandValue = "";
foreach (DataColumn dataColumn in table.Columns)
{
sqlCommandValue += dataColumn + "],[";
}
sqlCommandValue = "[" + sqlCommandValue.TrimEnd(',');
sqlCommandValue = sqlCommandValue.Remove(sqlCommandValue.Length - 2);
sqlCommandInsert = "INSERT into [" + SheetName + "] (" + sqlCommandValue + ") VALUES(";
int columnCount = table.Columns.Count;
Excel_OLE_Con.Open();
Excel_OLE_Cmd.CommandTimeout = 0;
foreach (DataRow row in table.Rows)
{
string columnvalues = "";
for (int i = 0; i < columnCount; i++)
{
int index = table.Rows.IndexOf(row);
columnvalues += "'" + table.Rows[index].ItemArray[i].ToString() + "',";
}
columnvalues = columnvalues.TrimEnd(',');
var command = sqlCommandInsert + columnvalues + ")";
Excel_OLE_Cmd.CommandText = command;
Excel_OLE_Cmd.ExecuteNonQuery();
}
Excel_OLE_Con.Close();
}
}
public void Error(string ActualSheetName)
{
//USE ADO.NET Connection from SSIS Package to get data from table
string con = Dts.Connections["oledb_conn"].ConnectionString.ToString();
OleDbConnection _connection = new OleDbConnection(con);
OleDbCommand cmd = new OleDbCommand();
//drop Excel file if exists
if (!string.IsNullOrEmpty(ActualSheetName))
{
//FileType='PremiumFile'"
query = "Select ErrorQuery,SheetName,FileType from pol.ErrorMapping Where SheetName = '" + ActualSheetName + "' and FileType='PremiumFile'";
cmd.CommandType = CommandType.Text;
cmd.CommandText = query;
cmd.CommandTimeout = 0;
cmd.Connection = _connection;
_connection.Open();
DataTable dt_ErrorInfo = new DataTable();
dt_ErrorInfo.Load(cmd.ExecuteReader());
//cmd.ExecuteNonQuery();
_connection.Close();
if (dt_ErrorInfo != null && dt_ErrorInfo.Rows.Count > 0)
{
foreach (DataRow dt_ErrorInfo_row in dt_ErrorInfo.Rows)
{
query = dt_ErrorInfo_row["ErrorQuery"].ToString();
cmd.CommandType = CommandType.Text;
cmd.CommandText = query;
//cmd.CommandTimeout = 600;
cmd.Connection = _connection;
cmd.CommandTimeout = 0;
_connection.Open();
DataTable dt_Actual_data = new DataTable();
dt_Actual_data.Load(cmd.ExecuteReader());
//cmd.ExecuteNonQuery();
_connection.Close();
FileName = PackageName + dt_ErrorInfo_row["FileType"].ToString();
//TableName = "ErrorFileInfo ";
//Construct ConnectionString for Excel
connstring = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + FolderPath + FileName + ";" + "Extended Properties=\"Excel 12.0 Xml;HDR=YES;\"";
string SheetName = "";
object[] array = dt_ErrorInfo_row.ItemArray;
SheetName = array[1].ToString();
//Load Data into DataTable from SQL ServerTable
//string queryString = "SELECT * from " + TableName + " ";
//OleDbDataAdapter adapter = new OleDbDataAdapter(query, _connection);
DataSet ds = new DataSet();
ds.Tables.Add(dt_Actual_data);
//adapter.Fill(ds);
if (ds.Tables[0].Rows.Count > 0)
{
ExportExcelFile(ds, connstring, SheetName);
flag++;
}
}
}
}
}
#region ScriptResults declaration
/// <summary>
/// This enum provides a convenient shorthand within the scope of this class for setting the
/// result of the script.
///
/// This code was generated automatically.
/// </summary>
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
}
}
when i am reading excel(2010) file, "External table is not in the expected format." error occurs. i am using Oledb connection to read excel file.please provide me best solution for this issue. thank you...
string connectionstring = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filePath + ";Extended Properties='Excel 12.0;IMEX=1;HDR=YES'";
using (OleDbConnection conn = new OleDbConnection(connectionstring))
{
try
{
conn.Open();
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = conn;
System.Data.DataTable dtExcelSchema;
dtExcelSchema = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
string firstSheet = "";
int count = dtExcelSchema.Rows.Count;
conn.Close();
//Read Data from First Sheet
conn.Open();
DataTable dt = new DataTable();
var tempDataTable = (from dataRow in dtExcelSchema.AsEnumerable()
where !dataRow["TABLE_NAME"].ToString().Contains("FilterDatabase")
select dataRow).CopyToDataTable();
dt = tempDataTable;
firstSheet = dt.Rows[0]["TABLE_NAME"].ToString();
if (!firstSheet.EndsWith("$"))
{
firstSheet = dt.Rows[0]["TABLE_NAME"].ToString() + "$";
}
cmd.CommandText = "select * from [" + firstSheet + "]";
string query1 = "SELECT count(*) FROM [" + firstSheet + "]";
cmd = new OleDbCommand(query1, conn);
cmd.CommandText = query1;
if (Convert.ToInt32(cmd.ExecuteScalar()) > 0)
{
string sheetName = firstSheet.Replace(" ", "").Replace("'", "");
string query = "SELECT * FROM [" + sheetName + "]";
dtnew.TableName = firstSheet;
OleDbDataAdapter oda = new OleDbDataAdapter(query, conn);
oda.Fill(dtnew);
}
}
catch (Exception ex)
{
}
}
I am creating a sharepoint webpart solution where i need to upload a excel file
Here is my code:
string tempFilename = "";
SPSecurity.RunWithElevatedPrivileges(delegate
{
tempFilename = System.IO.Path.GetTempFileName();
flUpload.SaveAs(tempFilename);
string connectionString = string.Format("Provider=Microsoft.Jet.OLEDB.4.0; data source={0}; Extended Properties=\"Excel 8.0;HDR=No;IMEX=1\";", tempFilename);
connectionString = #"Provider=Microsoft.ACE.OLEDB.14.0;Data Source="+tempFilename+#";ExtendedProperties=""Excel 12.0;HDR=YES;""";
var adapter = new OleDbDataAdapter("SELECT * FROM [Failed Trades$]", connectionString);
var ds = new DataSet();
adapter.Fill(ds, "anyNameHere");
DataTable data = ds.Tables["anyNameHere"];
The Connection String generated is:
Provider=Microsoft.ACE.OLEDB.14.0;Data Source=C:\Windows\ServiceProfiles
\NetworkService\AppData\Local\Temp\Demo1.xls;
ExtendedProperties="Excel 12.0;HDR=YES;"
I had looked hundrededs of solutions but none of them is workimg.
Here are few solutions what i tried:
Installed setups from microsoft (64 bit)
Change the application pool with 32 bit enabled but that caused my pool to stopped again and again
I checked my DSN as well
Change the version number of the OLEDB driver in your connection string from:
Microsoft.ACE.OLEDB.14.0
to
Microsoft.ACE.OLEDB.12.0
This should work presuming you've installed the Microsoft Access Database Engine 2010 Redistributable.
You can try this:
In ODBC Data source administration click in "User DNS", and click "Excel files", and "Configuration..."
In the next window: "ODBC Microsoft Excel Setup", click in "Version" and see the list of drives.
Put the correct version in your connection String. like:
Microsoft.ACE.OLEDB.12.0 or Microsoft.ACE.OLEDB.14.0
You can select all:
public string tables(string strFileName)
{
DataTable dt = null;
try
{
recarrega = false;
OleDbConnection conn = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.15.0;Data Source=" + strFileName + ";Extended Properties=\"Excel 12.0 Xml;HDR=YES\";");
conn.Open();
dt = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
conn.Close();
}
catch (Exception a)
{
MessageBox.Show("15 - " + a.Message);
try
{
recarrega = false;
OleDbConnection conn = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.14.0;Data Source=" + strFileName + ";Extended Properties=\"Excel 12.0 Xml;HDR=YES\";");
conn.Open();
dt = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
conn.Close();
}
catch (Exception b)
{
MessageBox.Show("14 - " + b.Message);
try
{
recarrega = false;
OleDbConnection conn = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.13.0;Data Source=" + strFileName + ";Extended Properties=\"Excel 12.0 Xml;HDR=YES\";");
conn.Open();
dt = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
conn.Close();
}
catch (Exception c)
{
MessageBox.Show("13 - " + c.Message);
try
{
recarrega = false;
OleDbConnection conn = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + strFileName + ";Extended Properties=\"Excel 12.0 Xml;HDR=YES\";");
conn.Open();
dt = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
conn.Close();
}
catch (Exception d)
{
MessageBox.Show("12 - " + d.Message);
}
}
}
}
}
I have developed a web application, which runs good when executed from Visual studio.
The theme of the application is to get the content in the excel file and display it.
We had a file upload control in our application, to get the excel file.
It works like charm when executed from the VS and i could see the desired result, but it is giving error when browsed through IIS.
Code is developed in Framework 4.0
The excel file is not uploading, and throws an error that error occured while reading the file.
Here is my code ..
Can you detect what goes wrong when browsed through IIS ?
DataSet dsRates = new Schemas.Rates();
DataTable dtExcel = new DataTable();
dtDBTable = dsRates.Tables[0];
DataTable dtColumnNameNotFound = new DataTable();
FileStream stream;
string changed = string.Empty;
string FilePath = string.Empty;
try
{
if (ValidateUserInputs())
{
DataSet dsExcel = new DataSet();
OleDbConnection con = new OleDbConnection();
try
{
if (fupExtract.HasFile == true)
{
FilePath = Server.MapPath("~/Temp/" + fupExtract.PostedFile.FileName);
fupExtract.SaveAs(FilePath);
}
else
{
fupExtract = ((FileUpload)Session["FileUploadCtrl"]);
FilePath = Server.MapPath("~/Temp/" + fupExtract.PostedFile.FileName);
fupExtract.SaveAs(FilePath);
}
//Read the Excel Data in to Datatable
string _ConnectionString = string.Empty;
string _Extension = Path.GetExtension(FilePath);
if (_Extension.Equals(".xls", StringComparison.CurrentCultureIgnoreCase))
{
_ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + FilePath + ";Extended Properties=" + (char)34 + "Excel 8.0;HDR=NO;IMEX=1;" + (char)34;
}
//Use ACE OleDb
else if (_Extension.Equals(".xlsx", StringComparison.CurrentCultureIgnoreCase))
{
_ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + FilePath + ";Extended Properties=" + (char)34 + "Excel 8.0;HDR=NO;IMEX=1;" + (char)34;
}
else
{
lblMessage.Text = fupExtract.FileName + "is not a supported format, only '.xls|.xlsx' files are supported";
return;
}
int i = 0;
con = new OleDbConnection(_ConnectionString);
con.ResetState();
con.Open();
DataTable dt = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
foreach (DataRow Sheet in dt.Rows)
{
OleDbDataAdapter daExcel = new OleDbDataAdapter("SELECT * FROM [" + Sheet["TABLE_NAME"].ToString().Trim() + "]", con);
DataTable dtData = new DataTable();
daExcel.Fill(dtData);
var filteredRows = dtData.Rows.Cast<DataRow>().Where(row => row.ItemArray.Any(field => !(field is System.DBNull)));
if (filteredRows.Count() > 0)
{
dsExcel.Tables.Add(dtData);
}
i++;
}
con.Close();
}
catch (Exception ex)
{
lblMessage.Text = "Error occured while reading the file";
con.Close();
}
finally
{
if (File.Exists(FilePath))
{
File.Delete(FilePath);
}
}
Please help
Thanks,
Tou can use Interop in order to read your excel document
object misValue = System.Reflection.Missing.Value;
var xlApp = new Excel.ApplicationClass();
var xlWorkBook = xlApp.Workbooks.Open("yourFile.xls", 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
var xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
Console.Write(xlWorkSheet.get_Range("A1","A1").Value2.ToString());
xlWorkBook.Close(true, misValue, misValue);
xlApp.Quit();
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlApp);
I've got the answer to my question.
It's that I haven't installed Office 64-bit and Microsoft.ACE.OLEDB.12.0. The one I'm using is 32-bit.
I need to fetch a sheet from excel to a datatable. I first tried with LinqToExcel library, but this fetched the large numbers from the excel sheet as exponential numbers. I'm talking about big numbers like "2352143523453452334544". Only if they are formated as text it would work ok.
After that i've tried this :
OleDbConnection con = null;
System.Data.DataTable dt = null;
System.Data.DataTable dataTable1 = new System.Data.DataTable();
string conStr = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + UploadFileName + ";Extended Properties=Excel 8.0;";
string sql_xls;
con = new OleDbConnection(conStr);
con.Open();
//OracleDataAdapter oda = new OracleDataAdapter();
//OracleCommand cmd = new OracleCommand("select * from [Sheet1$]", con);
dt = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
string[] excelSheetNames = new string[dt.Rows.Count];
int i = 0;
foreach (System.Data.DataRow row in dt.Rows)
{
excelSheetNames[i] = row["TABLE_NAME"].ToString(); i++;
}
sql_xls = "SELECT * FROM [" + excelSheetNames[0] + "]";
OleDbDataAdapter dataAdapter = new OleDbDataAdapter(sql_xls, conStr);
System.Data.DataSet myDataSet = new System.Data.DataSet();
dataAdapter.Fill(myDataSet, "ExcelInfo");
dataTable1 = myDataSet.Tables["ExcelInfo"];
This one returned the same values in the same conditions as null.
Isn't there a simple way to fetch data from a excel file as it is? No conversions, no nothing. Just take it all as a string, and put it into a datatable ?
This is what i used and it worked for me:
private DataTable LoadXLS(string strFile, String sheetName)
{
DataTable dtXLS = new DataTable(sheetName);
try
{
string strConnectionString = "";
if(strFile.Trim().EndsWith(".xlsx"))
{
strConnectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0 Xml;HDR=YES;IMEX=1\";", strFile);
}
else if(strFile.Trim().EndsWith(".xls"))
{
strConnectionString = string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=1\";", strFile);
}
OleDbConnection SQLConn = new OleDbConnection(strConnectionString);
SQLConn.Open();
OleDbDataAdapter SQLAdapter = new OleDbDataAdapter();
string sql = "SELECT * FROM [" + sheetName + "$]";
OleDbCommand selectCMD = new OleDbCommand(sql, SQLConn);
SQLAdapter.SelectCommand = selectCMD;
SQLAdapter.Fill(dtXLS);
SQLConn.Close();
}
catch (Exception)
{
throw;
}
return dtXLS;
}
But you can try to export to CSV as well:
LinqToCSV