My Excel workbook is stored in some location, Basically i'm using Export to excel from a gridview when i Click on a button.
All works fine,
My Question is, " I want to first lookup the file, and if its already present, then update it with the data i got with my gridview, if there are any new data present."
My function just creates a whole lot of new data which overrides the previous one.
Thanks
You can check for the file first as follows
string filePath = Request.PhysicalApplicationPath + "filename.xls";
FileInfo imageFile = new FileInfo(filePath);
bool fileExists = imageFile.Exists;
Label1.Text = "File exits?: " + fileExists.ToString();
Here is a code for reading and updating the excel file
var myConnection = new OleDbConnection("provider=Microsoft.Jet.OLEDB.4.0;Data Source='c:\\Language_Batch1_OneClick.xls';Extended Properties=Excel 8.0;"); ;
var myCommand = new OleDbCommand();
var upCommand = new OleDbCommand();
int i = 0;
try
{
string sql = null;
myConnection.Open();
myCommand.Connection = myConnection;
sql = "select ANSWER_CODE,Punjabi from [Batch_Lang_1$]";
myCommand.CommandText = sql;
var dataReader = myCommand.ExecuteReader();
while (dataReader.Read())
{
var langText = Convert.ToBase64String(Encoding.UTF8.GetBytes(dataReader["Punjabi"].ToString()));
if (langText.Length >= 1000)
{
continue;
}
var ansCode = dataReader["ANSWER_CODE"].ToString();
sql = "update [Batch_Lang_1$] set Punjabi= '" + langText + "' where ANSWER_CODE='" + ansCode + "'";
upCommand.Connection = myConnection;
upCommand.CommandText = sql;
upCommand.ExecuteNonQuery();
i++;
}
Here is a link which has code for reading and updating the excel file.
C# Convert MS Excel column to utf-8 and then to base64
Related
I'm frustrated because i can't solve this problem...
Well, i has been making a desktop application in C#, i almost complete the application,
But i have a big problem.
My application import an excel workbook who has some information that it is showed in a Gridview.
It works ok, but my app update or modified the data that is showed in a gridview, only one column that is called Balance.
I want to update this column in my excel workbook, is like an update condition in SQL, for example
I have this information that is imported to my app.
If i modify in my app some row, for example the row that has the order "12345", i want to update in my excel workbook the column called Balance of that row.
I has been trying with this code:
string order = textBox1.Text;
string balance = textBox2.Text;
filePath = openFileDialog1.FileName;
extension = Path.GetExtension(filePath);
header = "Yes";
OleDbConnection MyConnection = new OleDbConnection(conStr); ;
OleDbCommand myCommand = new OleDbCommand();
string sql = null;
MyConnection.Open();
myCommand.Connection = MyConnection;
sql = "UPDATE [" + sheetName + "] SET [" + sheetName + "].[Order]=123 WHERE [" + sheetName + "].[Balance]=12313";
myCommand.CommandText = sql;
myCommand.ExecuteNonQuery();
MyConnection.Close();
And if i debug the code it is the sentence that is executed, and i think that it is ok, but it doesn't works.
UPDATE ['12234$'] SET ['12234$'].[Order]=123 WHERE ['12234$'].[Balance]=12313
It give me this error:
Message=No value given for one or more required parameters.
Source=Microsoft Access Database Engine
Consider using an NuGet package to work with Excels instead. EPPlus is an excellent one.
using (var package = new ExcelPackage(#"someFile.xlsx")
{
var sheet = package.Workbook.Worksheets.First();
sheet.Cells["E2"].Value = 12345.32M;
package.Save();
}
Sql is no longer possible, but you can use Linq:
using (var package = new ExcelPackage(#"someFile.xlsx")
{
var sheet = package.Workbook.Worksheets.First();
int rowIndex = sheet.Cells["C2:C5"].First(x => int.Parse(x.Value.ToString()) == 12345).Start.Row;
const int balanceColumnIndex = 5;
sheet.Cells[rowIndex, balanceColumnIndex].Value = 12313M;
package.Save();
}
I wrote a series about EPPlus on my blog.
This is just a thought - but is your SQL-like string set up correctly?
If you're trying to update the balance for a certain order, you'd want that to be in your SET command.
So, something along the lines of...
UPDATE ['12234$'] SET ['12234$'].[Balance]=12313 WHERE ['12234$'].[Order]=12345
//try this solution
string connString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + Directory.GetCurrentDirectory() + "/swtlist.xlsx;" +
#"Extended Properties='Excel 12.0;HDR=Yes;';Persist Security Info=False;";
using (OleDbConnection connection = new OleDbConnection(connString))
{
connection.Open();
try
{
DataTable dt = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
OleDbCommand cmd = new OleDbCommand("UPDATE [Feuil1$] SET d='yes' ", connection);
cmd.ExecuteNonQuery();
connection.Close();
}
catch (Exception ex) { }
}
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()
I use the Microsoft.ACE.OLEDB.12.0 driver in my C# to read and write to excel files (XLS).
The extended properties for my reader looks like : Excel 8.0;HDR=NO;IMEX=1;
and for writer looks like : Excel 8.0;HDR=NO;IMEX=0;
This is the scenario :
I read from an excel file, say input.xls , and create a new output.xls file and write to it using my writer.
Now I open the file output.xls in MS Excel, and add a few more rows to it.
Next, I feed my output.xls as input to my program, and when I debug, I see that it reads only the rows originally written using OleDb. It does not read any of the new rows I added and the writer spits out the rows that were read.
Is this how OleDb works? i.e. treat the database as locked by it, and doesn't value external inserts.
Or could there be an issue with how I create and save the files?
private void Initialize(string fileName, FileType fileType)
{
string connectionString = GetConnectionString(fileName, fileType);
string sheet;
using (OleDbConnection connection = OpenConnection(connectionString))
{
DataTable sheets = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
}
tableName = "[ListingDetails]";
conn = new OleDbConnection();
conn.ConnectionString = connectionString;
conn.Open();
cmd1 = new OleDbCommand();
cmd1.Connection = conn;
cmd1.CommandText = string.Format(CultureInfo.InvariantCulture, #"CREATE TABLE {0} {1}", tableName, fieldstring);
int x = cmd1.ExecuteNonQuery();
}
public void InsertRow(string[] data)
{
StringBuilder fieldString = new StringBuilder();
fieldString.Append("(");
foreach (var h in headers)
{
fieldString.Append(" ["+h+"], ");
}
fieldString.Remove(fieldString.Length - 2, 2);
fieldString.Append(")");
StringBuilder dataString = new StringBuilder();
dataString.Append("('");
foreach (var d in data)
{
if(d!=null)
dataString.Append(d.Replace("'", "''") + "', '");
else
dataString.Append("', '");
}
dataString.Remove(dataString.Length - 4, 4);
dataString.Append("')");
cmd1.CommandText = string.Format(CultureInfo.InvariantCulture, #"INSERT INTO {0} {1} values {2}", tableName, fieldString, dataString);
int x = cmd1.ExecuteNonQuery();
}
For closing the file, I just do a conn.Close();
I'm somehow suspecting the way I'm creating/using the sheet here in the Initialize() method.
P.S. I've seen a similar question, but the issue there seemed to be something with the Data and IMEX flag not being set to 1. Let me tell you before hand that this is not a duplicate question.
Thanks
I used the code below, which is really a simplification of your code but with a few minor changes. It works everytime and I can even have Excel open and watch the rows being inserted as I execute the code. I can then make edits to the file and subsequently load them into a datagrid while the file is still open and without ever having saved the changes.
private void Initialize(string fileName, string tableName)
{
string connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileName + ";Mode=ReadWrite;Extended Properties=\"Excel 8.0;HDR=NO\"";
string fieldstring = "(ID int, Field1 char(255), Field2 char(255))";
using (OleDbConnection conn = new OleDbConnection(connectionString))
{
conn.Open();
using (OleDbCommand cmd = new OleDbCommand())
{
cmd.Connection = conn;
cmd.CommandText = string.Format(CultureInfo.InvariantCulture, #"CREATE TABLE [{0}] {1}", tableName, fieldstring);
cmd.ExecuteNonQuery();
}
conn.Close();
}
}
public void InsertRow(string fileName, string tableName, string data)
{
string connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileName + ";Mode=ReadWrite;Extended Properties=\"Excel 8.0;HDR=YES\"";
string headers = "ID,Field1,Field2";
using (OleDbConnection conn = new OleDbConnection(connectionString))
{
conn.Open();
using (OleDbCommand cmd = new OleDbCommand())
{
cmd.Connection = conn;
cmd.CommandText = string.Format(CultureInfo.InvariantCulture, #"INSERT INTO [{0}$] ({1}) values({2})", tableName, headers, data);
txtQuery.Text = cmd.CommandText;
cmd.ExecuteNonQuery();
}
conn.Close();
}
}
Create the file with
Initialize("C:\\path\\to\\file\\Test File.xls", "ListingDetails");
Insert test rows with
for (int i = 0; i < 10; i++)
{
InsertRow("C:\\path\\to\\file\\Test File.xls", "ListingDetails",
"'" + i.ToString() + "','test" + (i + 2).ToString() + "','test" + (i + 5).ToString() + "'");
}
I cleaned up the code surrounding the creation and disposal of the OleDb objects. This may have been causing problems for you, I'm not sure, but this way at least you know that everything is getting finished off properly.
Hope this helps.
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>
I've got a c# program, which is connected to dbf file:
OdbcConnection oconn = new OdbcConnection();
oconn.ConnectionString =
"Driver={Microsoft Visual FoxPro Driver};SourceType=DBF;SourceDB=" + pelna_sciezka + ";Exclusive=No; Collate=Machine;NULL=NO;DELETED=NO;BACKGROUNDFETCH=NO;";
oconn.Open();
OdbcCommand ocmd = oconn.CreateCommand();
ocmd.CommandText = #"SELECT * FROM " + pelna_sciezka + " where Kod_kontr = '" + row.KNH_KOD + "'";
// ocmd.ExecuteNonQuery();
OdbcDataReader odr = ocmd.ExecuteReader();
while (odr.Read())
{
kod_kontr = odr["Kod_kontr"].ToString();
Nzwakontr1 = odr["Nzwakontr1"];
Nzwakontr2 = odr["Nzwakontr2"];
}
connection is working very well, but when I want to assemble data to local string variables (kod_kontr, nzwakontr1), all i get for a value is System.Byte[]. When I want to get the other types of data (f.ex. date, numeric, etc)from this dbf, everything is working well. The problem is only for varchar data . How could I solve my problem?
Thanx for any help
According to Antonio Bakula help i've read the answer:
I must change from ODBC to OLE, and:
- change connectionstring to:
oconn.ConnectionString = "Provider=vfpoledb.1;Data Source="+pelna_sciezka+";Collating Sequence=machine";
change code for that:
OleDbDataReader odr = ocmd.ExecuteReader();
while (odr.Read())
{
// byte[] A = Encoding.GetEncoding(Encoding.Default.CodePage).GetBytes(odr.GetString(0));
// string p = Encoding.Unicode.GetString((Encoding.Convert(Encoding.GetEncoding(850), Encoding.Unicode, A)));
kod_kontr = OdczytajTabliceBajtow(odr["Kod_kontr"]);
Nzwakontr1 = OdczytajTabliceBajtow(odr["Nzwakontr1"]);
Nzwakontr2 = OdczytajTabliceBajtow(odr["Nzwakontr2"]);
}
where OdczytajTabliceBajtow:
private string OdczytajTabliceBajtow(object p)
{
Encoding enc8 = Encoding.ASCII;
string wynik = "";
Byte[] bytes = (Byte[])p;
StringBuilder sb = new StringBuilder();
sb.Append(Encoding.ASCII.GetChars(bytes));
wynik = sb.ToString();
return wynik;
}
This is the solution of my problem. Thank you all for help.
I reccomend that you use OleDB driver for FoxPro and you will not have these problems, and there will be noticable gain in speed, here is the link
http://www.microsoft.com/en-us/download/details.aspx?id=14839
And then you will get value from DataReader as string for Character fields