exporting data set to excelsheet - c#

I am new to excel automation in C# so I am confused about this. I have imported an excel in a dataset and I have done some updates in the dataset as per my requirement. now I want to export that dataset to that input sheet so that I can see the updates done in the dataset reflected in the datasheet. what will be the best approach for exporting dataset to excel.
below is the code of how I am opening the excel sheet:
string sConnection = null;
OleDbConnection oleExcelConnection = default(OleDbConnection);
sConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\input.xls;Extended Properties=\"Excel 12.0;HDR=No;IMEX=1\"";
oleExcelConnection = new OleDbConnection(sConnection);
oleExcelConnection.Open();
string sqlquery = "Select * From [c:\input.xls]";
DataSet ds = new DataSet();
OleDbDataAdapter da = new OleDbDataAdapter(sqlquery, oleExcelConnection);
da.Fill(ds);
System.Data.DataTable dt = ds.Tables[0];
/* 10 to 12 linq queries on dt*/
-> now here I want to export the updated dt to input.xls

after research of many hours, I found a way to write an excel using datatable. Although, my original requirement was to update the original sheet, I guess I will have to be happy with creating a new output sheet from scratch. the solution is given below:
//open file
StreamWriter wr = new StreamWriter(#"D:\\Book1.xls");
// dt is the DataTable needed to be dumped in an excel sheet.
try
{
for (int i = 0; i < dt.Columns.Count; i++)
{
wr.Write(dt.Columns[i].ToString().ToUpper() + "\t");
}
wr.WriteLine();
//write rows to excel file
for (int i = 0; i < (dt.Rows.Count); i++)
{
for (int j = 0; j < dt.Columns.Count; j++)
{
if (dt.Rows[i][j] != null)
{
wr.Write(Convert.ToString(dt.Rows[i][j]) + "\t");
}
else
{
wr.Write("\t");
}
}
//go to next line
wr.WriteLine();
}
//close file
wr.Close();
}
catch (Exception ex)
{
throw ex;
}

http://www.codeproject.com/Tips/705470/Read-and-Write-Excel-Documents-Using-OLEDB
private void WriteExcelFile()
{
string connectionString = GetConnectionString();
using (OleDbConnection conn = new OleDbConnection(connectionString))
{
conn.Open();
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = conn;
cmd.CommandText = "CREATE TABLE [table1] (id INT, name VARCHAR, datecol DATE );";
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO [table1](id,name,datecol) VALUES(1,'AAAA','2014-01-01');";
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO [table1](id,name,datecol) VALUES(2, 'BBBB','2014-01-03');";
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO [table1](id,name,datecol) VALUES(3, 'CCCC','2014-01-03');";
cmd.ExecuteNonQuery();
cmd.CommandText = "UPDATE [table1] SET name = 'DDDD' WHERE id = 3;";
cmd.ExecuteNonQuery();
conn.Close();
}
}
Google is your friend =)

Related

Importing excel file into SQL with different schema (asp.net C#)

I'm building a program where the user imports an excel file to a database (SQLServer)... But I Do not want to specify the columns name cause it makes my program very limit, to those column names....
I don't know how to work with datatable and rows very well, but I think its the only way right? (im a newbie, sorry)
Here's the code Guys:
rotected void Upload_Click(object sender, EventArgs e)
{
string sSheetName;
DataTable dtTablesList = new DataTable();
string excelPath = Server.MapPath("~/Nova pasta/") + Path.GetFileName(FileUpload1.PostedFile.FileName);
string filepath = Server.MapPath("~/Nova pasta/") + Path.GetFileName(FileUpload1.FileName);
string filename = Path.GetFileName(filepath);
FileUpload1.SaveAs(excelPath);
string ext = Path.GetExtension(filename);
String strConnection = #"Data Source=PEDRO-PC\SQLEXPRESS;Initial Catalog=costumizado;Persist Security Info=True;User ID=sa;Password=1234";
string excelConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filepath + ";Extended Properties=\"Excel 12.0 Xml;HDR=YES;IMEX=1;\"";
OleDbConnection excelConnection = new OleDbConnection(excelConnectionString);
excelConnection.Open();
dtTablesList = excelConnection.GetSchema("Tables");
if (dtTablesList.Rows.Count > 0)
{
sSheetName = dtTablesList.Rows[0]["TABLE_NAME"].ToString();
for (int j = 0; j < dtTablesList.Rows.Count; j++)
{
for (int i = 0; i < dtTablesList.Columns.Count; i++)
{
Debug.Write(dtTablesList.Columns[i].ColumnName + " ");
Debug.WriteLine(dtTablesList.Rows[j].ItemArray[i]);
}
}
Debug.WriteLine(dtTablesList.Rows.Count);
foreach (DataRow dataRow in dtTablesList.Rows)
{
foreach (var item in dataRow.ItemArray)
{
Debug.WriteLine(item);
}
}
OleDbCommand cmd = new OleDbCommand("Select * from [" + sSheetName + "]", excelConnection);
cmd.ExecuteNonQuery();
}
I am not sure what exactly you are looking for.
In the past I have used a component called EPPlus.
I used this solution to turn a worksheet into a datatable.
See here: Excel to DataTable using EPPlus - excel locked for editing
Edit:
When you have the datatable of your excel worksheet you can do something like this:
using (SqlConnection con = new SqlConnection("connectionstring"))
{
try
{
con.Open();
foreach (DataRow dr in worksheetTable.Rows)
{
using (SqlCommand myCommand = new SqlCommand("insert into myTable (Products, column2) values (#prod, #col2)", con))
{
myCommand.CommandType = CommandType.Text;
myCommand.Parameters.AddWithValue("prod", dr[0]);
myCommand.Parameters.AddWithValue("col2", dr[1]);
int result = myCommand.ExecuteNonQuery();
}
}
}
catch (SqlException ex)
{
//handle errors here
}
catch (Exception ex)
{
//handle errors here
}
finally
{
con.Close();
}
}
(Code might not be perfect, I did not test it)
It depends a lot of the structure of your excel and database.
I hope this helps you.

Opening connections to multiple databases

I want to connect to multiple databases and want to run some query on through those connections, but it's not working.
string source = "10.0.0.0";
string user = "abc";
string password="abc";
DataTable dt = new DataTable();
for (int i = 0; i < dt.Rows.Count; i++)
{
string source = dt.Rows[i][2].ToString();
string user = dt.Rows[i][1].ToString();
int password = Convert.ToInt32(user) + 111;
OracleConnection conn = new OracleConnection("Data Source = " + source + ": 1521/rms; User id = " + user + "; Password=" + password + ";");
conn.Open();
OracleCommand cmd = new OracleCommand(" SELECT SUM(AI_TRN) FROM tr_rtl where DC_DY_BSN = '06-04-2016'and mall like '%" + Mallname.Text + "%' ", conn);
cmd.ExecuteNonQuery();
OracleDataAdapter oda = new OracleDataAdapter(cmd);
oda.Fill(dt);
dataGridView1.DataSource = dt;
conn.Close();
label1.Text = source;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
sorry i have posted the wrong code
What you probably will need to do is iterate through a list of connections and populate one data table with all the results. Here is an example:
List<OracleConnections> Connections = new List<OracleConnections>();
DataTable FinalResults = new DataTable();
foreach (var Connection in Connections)
{
using (Connection)
{
DataTable TemporaryTable = new DataTable();
Connection.Open();
OracleCommand Command = new OracleCommand("SomeCommandText", Connection);
OracleDataAdapter Adapter = new OracleDataAdapter(Command);
Adapter.Fill(TemporaryTable);
FinalResults.Merge(TemporaryTable);
}
}
This should give you all the results of each database/connection in one final table (Results) or you can do a dataset if it is different columns/data within each connection.
Updated to explain comments listed above.
string Source = "10.0.0.0";
string User = "abc";
string Password = "abc";
DataTable dt = new DataTable();
// Remove this or use another reference (different table), you just created the table ^, it has no rows. -> "for (int i = 0; i < dt.Rows.Count; i++)"

C# & SQL Server : searching all database columns and populating datagrid

I am writing a a C# application, and I am stuck at searching the database and populating a data grid view. However I want to use this with command builder.
The issue is, I need the search to work across all columns in the database. I thought using OR and LIKE statements would do this. But instead I get either invalid syntax or no column name exists in the search.
Does anyone know a solution?
My current .cs:
private void btnSearchJob_Click(object sender, EventArgs e)
{
try
{
SqlConnection con = new SqlConnection();
con.ConnectionString = (#"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=MTR_Database;Integrated Security=True");
string selectQuery = "SELECT * FROM dbo.[" + cmbJobName.Text + "] WHERE ([Job Name] LIKE " +txtSearchJob.Text+ " OR [Manufacturer] LIKE " +txtSearchJob.Text+ ")";
// DataAdapter
myDA = new SqlDataAdapter(selectQuery, con);
// SqlCommand
SqlCommand myCMD = new SqlCommand(selectQuery, con);
// DataAdapter to Command
myDA.SelectCommand = myCMD;
// Define Datatable
myDT = new DataTable();
// Command Builder (IS GOD!)
SqlCommandBuilder cb = new SqlCommandBuilder(myDA);
// Teach Command builder to be a boss!
myDA.UpdateCommand = cb.GetUpdateCommand();
myDA.InsertCommand = cb.GetInsertCommand();
myDA.DeleteCommand = cb.GetDeleteCommand();
// Fill the DataTable with DataAdapter information
myDA.Fill(myDT);
// Fill DataTable with Database Schema
myDA.FillSchema(myDT, SchemaType.Source);
// Bind The Data Table to the DataGrid
dataGridView1.DataSource = myDT;
// AutoSize Datagrid Rows and Colums to fit the Datagrid
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
}
// Catch Exception
catch (Exception ex)
{
MessageBox.Show(this, ex.Message, "SQL ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
NOTE:
I am aware of using parameters, I am simply using this to see if it will work when I will add parameters later.
this is what I use to get everything back into a DataTable
//'places the call to the system and returns the data as a datatable
public DataTable GetDataAsDatatable(List<SqlParameter> sqlParameters, string connStr, string storedProcName)
{
var dt = new DataTable();
var sqlCmd = new SqlCommand();
using (var sqlconn = new SqlConnection(connStr))
{
sqlCmd.Connection = sqlconn;
sqlCmd.CommandType = CommandType.StoredProcedure;
sqlCmd.CommandText = storedProcName;
sqlCmd.CommandTimeout = 5000;
foreach (var sqlParam in sqlParameters)
{
sqlCmd.Parameters.Add(sqlParam);
}
using (var sqlDa = new SqlDataAdapter(sqlCmd))
{
sqlDa.Fill(dt);
}
}
sqlParameters.Clear();
return dt;
}
//'places the call to the system and returns the data as a datatable
public DataTable GetDataAsDatatable(string connStr, string query)
{
var dt = new DataTable();
var sqlCmd = new SqlCommand();
using (var sqlconn = new SqlConnection(connStr))
{
sqlCmd.Connection = sqlconn;
sqlCmd.CommandType = CommandType.Text;
sqlCmd.CommandText = query;
sqlCmd.CommandTimeout = 5000;
using (var sqlDa = new SqlDataAdapter(sqlCmd))
{
sqlDa.Fill(dt);
}
}
return dt;
}
hopefully this is pretty self explanatory to you, however pass in a list of SQL Parameters, connection string, and the stored procedure name, or use the second one where you pass in the inline SQL and the connection string.
I think you are missing ' in the query. Try this...
string selectQuery = "SELECT * FROM dbo.[" + cmbJobName.Text + "] WHERE ([Job Name] LIKE '" +txtSearchJob.Text+ "' OR [Manufacturer] LIKE '" +txtSearchJob.Text+ "')";

Check row length if greater then 0 then print data and while printing add for (i = 0; i <= dt.Rows.Count - 1; i++)

Iam trying to print data base value and the radio buttons in to a div but my problem is first if there are no rows in the table i need to show that there are no rows and the second probllem i want to add for (i = 0; i <= dt.Rows.Count - 1; i++) for condition as am using radio buttons that are dynamically generated i need to add i means number to each fetch.
string xxx= SessionManager.xxxxxxxx;
string htmlStr = "";
using (MySqlConnection myConnection = new MySqlConnection(constr))
{
string oString = "Select * from xxxxx WHERE xxxx=#xxxx and xxxx=#xxxx ";
MySqlCommand oCmd = new MySqlCommand(oString, myConnection);
oCmd.Parameters.AddWithValue("#xxxx", "0");
oCmd.Parameters.AddWithValue("#xxxx", "0");
myConnection.Open();
using (MySqlDataReader oReader = oCmd.ExecuteReader())
{
while (oReader.Read())
{
string Name = oReader["xxxx"].ToString();
// string Pass = oReader["xxxx"].ToString();
htmlStr += "<tr><td>" + Name + "</td><td><input type='radio' name='Present' value='Present'></td><td><input type='radio' name='Absent' value='Absent'></td><td><input type='radio' name='Leave' value='Leave'></td></tr>";
}
myConnection.Close();
}
}
STUDENT_LIST.InnerHtml = htmlStr;
MySqlDataReader has a readonly property called as "HasRows". The usage of it is;
if(oReader.HasRows)
{
// Perform operation
}
else
// Some other operation
The link for detailed list of members and methods of MySqlDataReader is here
UPDATE:
If you are looking for an example for the usage of MySqlDataAdapter, I would suggest you to go through the DataSet & MySqlDataAdapter section of this link
Hope this helps.
SqlConnection con = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand("select * from your_table", con);
try
{
con.Open();
SqlDataAdapter sda = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
sda.Fill(ds);
int num = ds.Tables[0].Rows.Count;
for (int i = 0; i < num - 1; i++)
//Do something here
}
catch (Exception ex)
{
//...
}
finally
{
con.Close();
}
Hope it helps

How duplicate entries be prevented while using SqlBulkCopy?

I am importing excel data into sql server using SqlbulkCopy, but the problem is i want to prevent any duplicate records being entered. Is there a way by which duplicate can be ignored or deleted automatically?
protected void Button1_Click(object sender, EventArgs e)
{
string strFileType = System.IO.Path.GetExtension(FileUpload1.FileName).ToString().ToLower();
string strFileName = FileUpload1.PostedFile.FileName.ToString();
FileUpload1.SaveAs(Server.MapPath("~/Import/" + strFileName + strFileType));
string strNewPath = Server.MapPath("~/Import/" + strFileName + strFileType);
string excelConnectionString = String.Format(#"Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + strNewPath + "; Extended Properties=Excel 8.0;");
// Create Connection to Excel Workbook
using (OleDbConnection connection = new OleDbConnection(excelConnectionString))
{
var command = new OleDbCommand("Select ID,Data FROM [Sheet1$]", connection);
connection.Open();
// Create DbDataReader to Data Worksheet
using (DbDataReader dr = command.ExecuteReader())
{
// SQL Server Connection String
string sqlConnectionString = "Data Source=ARBAAZ-1B14C081;Initial Catalog=abc;Integrated Security=True";
con.Open();
DataTable dt1 = new DataTable();
string s = "select count(*) from ExcelTable";
string r = "";
SqlCommand cmd1 = new SqlCommand(s, con);
try
{
SqlDataAdapter da1 = new SqlDataAdapter(cmd1);
da1.Fill(dt1);
}
catch
{
}
int RecordCount;
RecordCount = Convert.ToInt32(cmd1.ExecuteScalar());
r = RecordCount.ToString();
Label1.Text = r;
con.Close();
int prv = Convert.ToInt32(r);
// Bulk Copy to SQL Server
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(sqlConnectionString))
{
bulkCopy.DestinationTableName = "ExcelTable";
SqlBulkCopyColumnMapping mapping1 = new SqlBulkCopyColumnMapping("excelid", "id");
SqlBulkCopyColumnMapping mapping2 = new SqlBulkCopyColumnMapping("exceldata", "data");
bulkCopy.ColumnMappings.Add(mapping1);
bulkCopy.ColumnMappings.Add(mapping2);
bulkCopy.WriteToServer(dr);
}
con.Open();
DataTable dt = new DataTable();
s = "select count(*) from ExcelTable";
r = "";
SqlCommand cmd = new SqlCommand(s, con);
try
{
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
}
catch
{
}
RecordCount = Convert.ToInt32(cmd.ExecuteScalar());
r = RecordCount.ToString();
Label1.Text = r;
con.Close();
int ltr = Convert.ToInt32(r);
if (prv == ltr)
{
Label1.Text = "No records Added";
}
else
{
Label1.Text = "Records Added Successfully !";
}
}
}
}
Can this problem be fixed by creating a trigger to delete duplicates? if yes how? i am a newbie i have never created a trigger.
Another problem is no matter what i try i am unable to get column mapping to work. I am unable to upload data when column names in excel sheet and database are different.
You can create INDEX
CREATE UNIQUE INDEX MyIndex ON ExcelTable(id, data) WITH IGNORE_DUP_KEY
And when you will insert data with bulk to db, all duplicate values will not inserted.
no, either you manage it on your dr object on you code before you load it into the db (like running a DISTINCT operation) or you create a trigger on the DB to check. The trigger will reduce the bulk insert's performace though.
Another option would be to bulk insert into a temp table and then insert into your destination table FROM your temp table using a select DISTINCT
as far as I remember,
you could filter out the redundant rows when importing from the excel file itself.
the following SQL query should be used in the OleDbCommand constructor.
var command = new OleDbCommand("Select DISTINCT ID,Data FROM [Sheet1$]", connection);

Categories

Resources