OleDb - Retrieving Excel worksheet names also retrieves Defined Names - asp.net

I am trying to retrieve a list of the worksheets in an Excel workbook, but the collection I get back has both the sheet names and the data column id's, which seem to be called 'Defined Names' in the original xlsx xml. Can you tell me how to return only the worksheet names?
The code I'm using is along the lines of:
OleDbConnection connExcel = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;"
+ #"Data Source=" + FilePath + ";"
+ #"Extended Properties=""Excel 8.0;HDR=Yes;""");
OleDbCommand cmdExcel = new OleDbCommand();
cmdExcel.Connection = connExcel;
connExcel.Open();
DataTable testTable = connExcel.GetSchema("Tables");
The contents of the resulting testTable collection contain entries under TABLE_NAME of:
DATA1
DATA2
DATA3
DATA4
DATA5
Sheet1$
TEST1
-TEST2
TESTHKEY
TESTKEYS
TESTVKEY
They all have a TABLE_TYPE of TABLE.
The original workbook corresponding to the above would have 1 worksheet containing 5 columns, the first row would contain a header. I'm only interested in the Sheet1$ entry. The spreadsheet is
created in Excel 2010, I'm trying to process it in an ASP.NET 4 app written in C#. Potentially, the worksheet name may have been changed so I can't guarrantee that it will always be Sheet1$.

My first thoughts were wrong so I came up with this as a workaround. The actual worksheet names returned should always end with $, so I hacked it to check for that. Messy but you get the general idea I'm sure.
OleDbConnection connExcel = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;"
+ #"Data Source=c:\test.xlsx;"
+ #"Extended Properties=""Excel 12.0 Xml;HDR=Yes;""");
OleDbCommand cmdExcel = new OleDbCommand();
cmdExcel.Connection = connExcel;
connExcel.Open();
DataTable testTable = connExcel.GetSchema("Tables");
String[] excelSheets = new String[testTable.Rows.Count];
int i = 0;
foreach (DataRow row in testTable.Rows)
{
excelSheets[i] = row["TABLE_NAME"].ToString();
if (excelSheets[i].EndsWith("$"))
{
Console.WriteLine(excelSheets[i] = row["TABLE_NAME"].ToString());
i++;
}
else
{
i++;
}
}
Console.ReadLine();

I had a similar issue but with the exception that it showed me Sheets that didn't exist in Excel. Even though this post is a bit old now, maybe somebody finds this and finds it helpful.
My Code:
//OpenFileDialog
try
{
OpenFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
OpenFileDialog.Filter = "XLSX Files(*.xlsx)|*.xlsx|All Files (*.*)|*.*";
OpenFileDialog.ShowDialog();
}
catch (Exception ex)
{
//some Error Message
}
//read into Combobox
try
{
OleDbConnection con = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + OpenFileDialog.FileName + ";Extended Properties=Excel 12.0;");
con.Open();
DataTable dt = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
con.Close();
this.Combobox.Items.Clear();
for (int i = 0; i < dt.Rows.Count; i++)
{
String sheetName = dt.Rows[i]["TABLE_NAME"].ToString();
sheetName = sheetName.Substring(0, sheetName.Length - 1);
//cheap Filter to filter out unneeded/wrong sheets
if (sheetName.Replace("'", " ").Replace("$", " ").TrimStart().TrimEnd().Contains("#") != true)
{
this.Combobox.Items.Add(sheetName.Replace("'", " ").Replace("$", " ").TrimStart().TrimEnd());
}
}
}
catch (Exception Ex)
{
//some Error Message
}
This might not be the best solution, but it works quite well for me.

private static string EXCEL_CONNECTIONSTRING = string.Format("Provider=Microsoft.ACE.OLEDB.12.0; data source={0}; Extended Properties=Excel 12.0;", "#{FILENAME}");
private IEnumerable<string> GetWorksheetNames(string excelFile)
{
var currentConnectionString = EXCEL_CONNECTIONSTRING.Replace("#{FILENAME}", excelFile);
using (OleDbConnection connection = new OleDbConnection(currentConnectionString))
{
OleDbCommand cmdExcel = new OleDbCommand();
cmdExcel.Connection = connection;
connection.Open();
DataTable dt = connection.GetSchema("Tables");
IEnumerable<string> excelSheets = dt.Rows.Cast<DataRow>().Select(row => row["TABLE_NAME"].ToString());
dt.Dispose();
connection.Close();
return excelSheets;
}
}

Related

How to create multiple CSV file in ASP .Net

I want to create multiple CSV file for every drop down Selected value. Even-though while debugging i can notice csv is appending for different drop down value but not writing another CSV file. do not know why and where i am doing mistake.
When i remove using block, and for second time its throwing error :
The process cannot access the file 'File path' because it is being used by another process.
I believe need to store all files on server but again same issue
i have added code to solve error but no change;
if (File.Exists(filePath))
File.Delete(filePath);
Button code
protected void btnGenerate_Click(object sender, EventArgs e)
{
List<int> stopWordArray = new List<int>();
foreach (ListItem listItem in ddlDepot.Items)
{
if (listItem.Selected)
{
string FileType = ddlqoutatfileType.SelectedItem.Text;
DateTime Qotation_Date = Convert.ToDateTime(txtdate.Text).AddDays(3);
var Qotation_Date_modified = Qotation_Date.ToShortDateString();
OracleCommand CmdB = new OracleCommand("Select DEPOT_CODE, PRODUCT_CODE, TO_CHAR(TO_DATE(UPLOAD_DATE,'DD/MM/YYYY'), 'DDMMYYY') as UPLOAD_DATE , TO_CHAR(TO_DATE(SALES_DATE,'DD/MM/YYYY'), 'DDMMYYYY') as SALES_DATE, ORDER_QTY, FILE_TYPE, ROUTE_CODE from SCM_SARAS_ORDERS_vw where File_Type = '" + FileType + "' and DEPOT_CODE =" + listItem.Value + " and SALES_DATE = TO_DATE('" + Qotation_Date_modified + "' , 'DD/MM/YYYY')", con);
CmdB.CommandType = CommandType.Text;
OracleDataAdapter daB = new OracleDataAdapter();
DataTable dtB = new DataTable();
daB.SelectCommand = CmdB;
daB.Fill(dtB);
string csv = string.Empty;
foreach (DataRow row in dtB.Rows)
{
foreach (DataColumn column in dtB.Columns)
{
csv += row[column.ColumnName].ToString().Replace(",", ";") + ',';
}
csv += "\r\n";
}
string fileName = "myfile.csv";
string filePath = Server.MapPath("~/file" + fileName);
using (StreamWriter sw = new StreamWriter(filePath, false))
{
sw.Write(csv);
}
}
}
}
I am not sure what do you mean about follow problem.
#but not writing another CSV file#
in your code, obviously, you wrote same file in the loop; why do not you change it to
string fileName = "myfile"+listItem.Value+".csv";//change filename?
string filePath = Server.MapPath("~/file" + fileName);
using (StreamWriter sw = new StreamWriter(filePath, false))
{
sw.Write(csv);
}

How to write data into Excel file and save it? EPPlus C#

I have the code to execute multiple stored procedures from SQl. However, I am having an issue on how to write the data from the stored procedures into the Excel file. After writing the data into the excel file, I would like to save the Excel workbook. How can I achieve this? Any help is very much appreciated.
This is what I have so far:
public static void ExecuteStoredProcedures()
{
using (SqlConnection connection = new SqlConnection("Data Source=the connection goes here.."))
{
SqlTransaction transaction;
connection.Open();
transaction = connection.BeginTransaction();
try
{
SqlCommand cmdOne = new SqlCommand("exec ", connection);
SqlCommand cmdTwo = new SqlCommand("exec", connection);
SqlCommand cmdThree = new SqlCommand("exec", connection);
cmdOne.ExecuteNonQuery();
cmdTwo.ExecuteNonQuery();
cmdThree.ExecuteNonQuery();
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
connection.Close();
}
}
}
public static void SaveExcelFile()
{
string SheetLocation = ConfigurationManager.AppSettings["SheetLocation"];
if (!System.IO.Directory.Exists(SheetLocation))
{
System.IO.Directory.CreateDirectory(SheetLocation);
}
ExecuteStoredProcedures(); //Should I call the method to load the data that comes from the stored procedures? Or what should I do to write the data into the file?
var newFile = new FileInfo(#"C:\Users\");
using (ExcelPackage xlPackage = new ExcelPackage(newFile))
{
xlPackage.Save();
}
}
Get data from stored procedures in the form of a Dataset or DataTables.
Create worksheet:
using (ExcelPackage xlPackage = new ExcelPackage(newFile))
{
ExcelWorksheet ws = xlPackage.Workbook.Worksheets.Add(AnyName);
}
Loop in Datatable rows and columns like a 2d array and create cells in the worksheet and add data in the created cells:
int rowIndex = 0
foreach (DataRow DataTableRow in dt.Rows)
{
int colIndex = 1;
rowIndex++;
foreach (DataColumn DataTableColumn in dt.Columns)
{
var cell = ws.Cells[rowIndex, colIndex];
cell.Value = DataTableRow[DataTableColumn.ColumnName];
colIndex++;
}
}

Create Data Dictionary to read column from DB

I am creating a WinForm Application that reads all the records from a certain column in a textfile. What I now need is a Data Dictionary that I can use to read records from the Database once the applications runs and prior to reading the TextFile. I need to read a specific column from the database and match it with the textfile. I am not sure how to go about creating a data dictionary. This is what I have so far.
This is to read the textfile, which is working fine.
using (StreamReader file = new StreamReader("C:\\Test1.txt"))
{
string nw = file.ReadLine();
textBox1.Text += nw + "\r\n";
while (!file.EndOfStream)
{
string text = file.ReadLine();
textBox1.Text += text + "\r\n";
string[] split_words = text.Split('|');
int dob = int.Parse(split_words[3]);
This is what I have so far to create the Data Dictionary.
public static Dictionary<int, string> dictionary = new Dictionary<int, string>();
You can use a SqlDataReader. Here is some code, you just need to modify it to suit your needs. I have added comments for you:
// declare the SqlDataReader, which is used in
// both the try block and the finally block
SqlDataReader rdr = null;
// Put your connection string here
SqlConnection conn = new SqlConnection(
"Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI");
// create a command object. Your query will go here
SqlCommand cmd = new SqlCommand(
"select * from Customers", conn);
try
{
// open the connection
conn.Open();
// 1. get an instance of the SqlDataReader
rdr = cmd.ExecuteReader();
while (rdr.Read())
{
string id = (int)rdr["SomeColumn"];
string name = (string)rdr["SomeOtherColumn"];
dictionary.Add(id, name);
}
}
finally
{
// 3. close the reader
if (rdr != null)
{
rdr.Close();
}
// close the connection
if (conn != null)
{
conn.Close();
}
}

Employee ID reflected in created by column instead of display name

I wrote a program to import data from excel sheet to sharepoint 2007 list. Around 11000 data gets imported. I have used the below code. My query is I wanted to put "employee's display name" in "created by" column. And im providing the same in excel sheet n in the code. But after the data gets imported I see that few employees data has reflected the created by column with their names. But for few it reflects EMPID only or EMPID + name. I debug the code It takes the right string to display but i did not understand y it gives such results. Also i am running the prog on my machine n not the server, so is it bcoz of this. As I am using test server and then only will deploy to production.
Code:
protected void btnImport_Click(object sender, EventArgs e)
{
using (SPSite site = new SPSite("URL"))
{
using (SPWeb web = site.OpenWeb())
{
webapp = web.Site.WebApplication;
webapp.FormDigestSettings.Enabled = false;
SPList list = web.Lists["List name"];
string connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\\Test.xlsx;Extended Properties=Excel 12.0";
OleDbConnection oledbConn = new OleDbConnection(connString);
oledbConn.Open();
OleDbCommand cmd = new OleDbCommand("SELECT * FROM [Sheet1$]", oledbConn);//contents from sheet1 is selected
OleDbDataAdapter oleda = new OleDbDataAdapter();
oleda.SelectCommand = cmd;
DataSet ds = new DataSet();
oleda.Fill(ds, "Employees");
DataTable dt = ds.Tables["Employees"];
DataView dv = new DataView(dt);
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite elevatedSite = new SPSite("URL"))
{
elevatedRootWeb = elevatedSite.OpenWeb();
}
});
foreach (DataRowView drv in dv)
{
EMPID = drv["Emp id"].ToString();
DispName = drv["Name"].ToString();
Title = drv["Title"].ToString();
getid = new SPQuery();
getid.Query = "<Where><Eq><FieldRef Name=’EMPID’ /><Value Type='Text'>" + EMPID + "</Value></Eq></Where><OrderBy><FieldRef Name='ID'/></OrderBy>";
check = list.GetItems(getid).GetDataTable();
if (check == null)
{
try
{
elevatedRootWeb.AllowUnsafeUpdates = true;
UserItem = list.Items.Add();
UserItem["Emp id"] = EMPID;
UserItem["Title"] = Title;
test = elevatedRootWeb.EnsureUser(PSNumber).ID + ";#" + DispName;
UserItem["Author"] = test;
UserItem.Update();
list.Update();
count++;
elevatedRootWeb.AllowUnsafeUpdates = false;
using (StreamWriter w = File.AppendText("D:\\Errorlog_SP2010.txt"))
{
Log(PSNumber + "Inserted successfully", w);
w.Close();
}
}
catch (Exception ex)
{
HttpContext.Current.Response.Write("<script>alert('Exception on adding item " + ex.Message + "')</script>");
using (StreamWriter w = File.AppendText("D:\\Errorlog_SP2010.txt"))
{
Log(ex.ToString()+ PSNumber, w);
w.Close();
}
}
}
check the "_catalogs/users/simple.aspx" list to see if the user on that site has thier information stored correctly.
This is important as the Author field takes it's value from what is displayed in this list, not exactly what you set.
See this question on how to fix this.

How to read data from Excel in Asp.Net

I am trying to read datas from an uploaded xls. I have used this code part:
OleDbConnection connection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Server.MapPath(fileName) + ";Extended Properties=Excel 8.0");
if (connection.State == ConnectionState.Closed)
connection.Open();
string query = "select * from [Sheet1$]";
OleDbDataAdapter da = new OleDbDataAdapter(query, connection);
DataSet ds = new DataSet();
da.Fill(ds);
But I get this error: External table is not in the expected format.
I am pretty sure I am giving the correct path. I was working and it is not. if it works then it wont fill the datatable. It gives an error that says that Sheet1$ object can not be found. Any help?
are you sure the excel version is correct? you may also want to wrap the extended properties in quotes as well. I would also recommend cleaning up your resources so you don't create memory leaks.
var path = Server.MapPath(fileName);
//where 8.0 may be a different version: 9 - 12?
var connectionString = string.Format(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended ""Properties=Excel 8.0""", path);
using(var connection = new OleDbConnection(connectionString))
using(var command = connection.CreateCommand())
{
connection.Open();
command.CommandText = "select * from [Sheet1$]";
var table = new DataTable();
using(var reader = command.ExeucteReader())
{
table.Load(reader);
return table;
}
}
Have a look at this thread:
Excel "External table is not in the expected format."
Maybe you should change provider as they suggest.
One other option is to use the OpenXML SDK to read the excel file. This could get you started:
http://msdn.microsoft.com/en-us/library/ff921204.aspx
string savePath = "/Assets/UploadedFiles/";
string fileName = "Activity.xls";
savePath += fileName;
OleDbConnection conn= new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + Server.MapPath(savePath) + ";Extended Properties='Excel 12.0;HDR=YES'");
if (conn.State == ConnectionState.Closed)
conn.Open();
string query = "select * from [Sheet1$]";
OleDbDataAdapter da = new OleDbDataAdapter(query, conn);
DataSet ds = new DataSet();
da.Fill(ds, "Activities");
dt = ds.Tables[0];
conn.Close();
save the file in the hard disk, then add a reference to Microsoft Excel 12.0 Object Library and declare the using:
using Excel = Microsoft.Office.Interop.Excel;
then instantiate a class and load the file to read the cell values, example:
Excel.Application xlApp ;
Excel.Workbook xlWorkBook ;
Excel.Worksheet xlWorkSheet ;
object misValue = System.Reflection.Missing.Value;
xlApp = new Excel.ApplicationClass();
xlWorkBook = xlApp.Workbooks.Open("file.xls", 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
MessageBox.Show(xlWorkSheet.get_Range("A1","A1").Value2.ToString());
xlWorkBook.Close(true, misValue, misValue);
xlApp.Quit();
EDIT 1:
If you don't want to install Office in the server, you can use the excellibrary that works similar, simple as (from the author page) :
// open xls file
Workbook book = Workbook.Load(file);
Worksheet sheet = book.Worksheets[0];
// traverse cells
foreach (Pair<Pair<int, int>, Cell> cell in sheet.Cells)
{
dgvCells[cell.Left.Right, cell.Left.Left].Value = cell.Right.Value;
}
// traverse rows by Index
for (int rowIndex = sheet.Cells.FirstRowIndex;
rowIndex <= sheet.Cells.LastRowIndex; rowIndex++)
{
Row row = sheet.Cells.GetRow(rowIndex);
for (int colIndex = row.FirstColIndex;
colIndex <= row.LastColIndex; colIndex++)
{
Cell cell = row.GetCell(colIndex);
}
}

Resources