In our application, we are saving the Excel files uploaded by the users to the database with varBinary data type. But, we would also like to retrieve back the data and be able to parse it to get the data in it (columns, rows).
I already know how to read an Excel File into a DataTable to get the data from it(like the code below), but I don't know how to do it if the DataSource is of type varbinary.
// Getting data from actual Excel File
var connectionString = string.Format("Provider=Microsoft.Jet.OLEDB.4.0; data source={0}; Extended Properties=Excel 8.0;", fileName);
var adapter = new OleDbDataAdapter("SELECT * FROM [Sheet1$]", connectionString);
var ds = new DataSet();
adapter.Fill(ds);
foreach (DataTable dt in ds.Tables) {
Response.Write(dt.TableName);
int i= 0;
foreach (DataRow dr in dt.Rows)
{
if (i < 2) { i++; continue; }
foreach (DataColumn dc in dt.Columns)
{
Response.Write(dc.ToString() + ": " + dr[dc.ToString()] + "<br />");
}
i++;
}
}
Is it possible to do with SqlServer 2012 and .NET 4? If yes, how?
Any feedback would be greatly appreciated.
Regards,
artsylar
The code you posted doesn't save an excel file into a table, it saves the contents of the excel file into a table. These are not the same.
In order to save the actual Excel file into a varbinary member of a table row, read the file from disk into a byte array, and then store the byte array into the varbinary. In the case of a Web application, use a file upload control to retrieve the file the user wishes to store to a temporary file storage area on the web server. Load the file to the database from there.
To reconstitute the file, retrieve the varbinary data into a byte array, and then write the byte array to a disk file. The file must be named appropriately, of course. In the case of a Web applciation, reconstitute the file in a local temporary location on the web server, and then send to the client's browser. They'll see a "save file" dialog, which will allow them to save the file locally on their machine.
Related
I'd like to use sql bulk copy in order to load data from *.xlsx file to the data base. But, I've faced the problem when file size is more than approximately 1mb. When I try to open OleDbConnection I get an error
No error message available, result code: E_FAIL(0x80004005)
Does anyone have an idea about such behavior?
P.S. If file size is less than mentioned above everything works as expected.
string connString = connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=Excel 12.0 Xml;";
// Create the connection object
OleDbConnection oledbConn = new OleDbConnection(connString);
// Open connection
oledbConn.Open();
// Create OleDbCommand object and select data from worksheet
OleDbCommand cmd = new OleDbCommand("SELECT * FROM [" + WorkSheetName + "$" + DataRange + "]", oledbConn);
OleDbDataReader dr = cmd.ExecuteReader();
string ProfDbBulkCopyConnString = ConfigurationManager.ConnectionStrings["DbBulkCopyConnString"].ToString();
SqlBulkCopy sb = new SqlBulkCopy(ProfDbBulkCopyConnString);
sb.ColumnMappings.Add("Status", "ActionStatus");
sb.ColumnMappings.Add("Process", "ProcessExec");
sb.DestinationTableName = "dba.Execute";
sb.WriteToServer(dr);
Just a brief description of fixing. For more information I recommend to visit:
https://social.msdn.microsoft.com/Forums/en-US/4d1eeb6d-436d-4595-8645-fde90b2f9b18/oledb-error-opening-large-excel-2007-files-on-web-server?forum=adodotnetdataproviders
Export to excel spreadsheet (XLSX) failing
Microsoft ACE OLEDB connection creating empty Excel when there are 166,110 rows
Essentially, xlsx format is some kind of zip archive with a bunch of xml files. So, first of all ACEOLEDB provider try to unzip all data directly to memory buffer, but in case of large xlsx file provider unable to unzip all data to memory buffer and it forced to create temp file on the hard drive. If user hasn't permission to the folder Content.MSO on hard drive mentioned problem appears.
Path to folder depends on your enviroment. In my case it is C:\Windows\SysWOW64\config\systemprofile\AppData\Local\Microsoft\Windows\Temporary Internet Files\Content.MSO (32-bit driver on 64-bit Windosw Server 2008 R2).
So, grant access to Content.MSO for user "IIS AppPool\DefaultAppPool" and problem goes away.
I have a website where one of the functions is importing excel sheets to a SQL database. Right now I am loading the data into a data table and then assigning a variable to a column index. That is working just fine, but if the excel sheet is in a different format then it wont import to the database.
Does anyone know of another way to import a specific column(s) into a SQL database other than using the column index? I have also used the column name, but what if the column name changes?
You can use like this.
var fileName = string.Format("{0}\\fileNameHere", Directory.GetCurrentDirectory());
var connectionString = string.Format("Provider=Microsoft.Jet.OLEDB.4.0; data source={0}; Extended Properties=Excel 8.0;", fileName);
var adapter = new OleDbDataAdapter("SELECT * FROM [workSheetNameHere$]", connectionString);
var ds = new DataSet();
adapter.Fill(ds, "anyNameHere");
DataTable data = ds.Tables["anyNameHere"];
The references for this is
1) How to read data from excel file using c#
2) Reading Excel files from C#
I hope it helps.
I have one question and I'm hoping it's an easy one for you.
(Windows Forms Application, C#, Framework 3.5, SQL Server 2008 R2)
I don't know how to open Excel (it is loaded in byte[] type) via OleDB.
So, what have I done:
I have uploaded Excel (.xls(x)) file via form, and saved it in a database as varbinary(max). Now I need to read that Excel file via oleDB. I've managed to load that file from database and saved it into byte[] variable. How can I open byte[] in oleDB?
When I uploaded file for the first time (before saving it to the database), I've opened it via OleDB with just passing file path. How can I access Excel's data when it is already stored in memory as byte[]?
If you want to read using OleDB, then you have to write the bytes to disk. For example, you could do this:
var filename = System.IO.Path.GetTempFileName();
// Assuming that fileBytes is a byte[] containing what you read from your database
System.IO.File.WriteAllBytes(filename, fileBytes);
var connection = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filename + ";Extended Properties=\"Excel 12.0;HDR=YES\"";
// Do your work on excel
using (System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection(connection))
{
conn.Open();
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "SELECT * FROM [Sheet1$]";
using (var rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
System.Diagnostics.Debug.WriteLine(rdr["ColumnName"]);
}
}
}
conn.Close();
}
//Cleanup
System.IO.File.Delete(filename);
If you don't want to write the file to disk, you could look into using a third party library that can read excel files from a memory stream. Tools like SpreadsheetGear or Aspose are commercial tools that can accomplish this.
I don't know anything about what library you're using to deal with your Excel data, but the first thing that comes to mind is that it almost certainly has a LoadFromFile method. It might not be called that, but that's what it does. See if it also has a LoadFromStream method, and if so, take your byte[] data and load it into a MemoryStream, and load the XLS from there.
emp.upload_file = Path.GetFileName(file.FileName);
emp as your table object created and file is HttpPostedFileBase file
Here is my code to read uploaded Excel file. Which is working absolutely fine for past 3 months.
var connectionString = GetOleDbConnectionString(file);
using (var dataAdapter = new OleDbDataAdapter("select * from [Sheet1$]", connectionString))
{
dataAdapter.Fill(ds, tableCount.ToString());
}
private static string GetOleDbConnectionString(string file)
{
var fileExtension = Path.GetExtension(file);
if (fileExtension.EqualsCCIC(".xlsx"))
{
return #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=Excel 12.0;".F(file);
}
}
Problem: Uploaded excel file got "StartDate" as first column. But this column also has employee name along with dates (I need to read this employee name to process this sheet).
I came across one new excel file (Excel2007 .xlsx). When I upload new file (Which has both employee name and dates) it is only reading dates from the column and ignoring employee names. my dataset showing (While debugging) those cells in data table as empty strings. According to business logic I need to know which employee these dates belongs to. I removed locks for entire sheet(cell formatting>>Protection>> lock) but still no use. How can I solve this problem? I have no clue...
It is successfully reading old files (2007 .xlsx) I didn't understand what is it that makes OLEDB to hide strings in Date column?
So you're saying that the new excel file is the issue? If so...
check the data in the file (particularly the first 8 rows in the employee name column)
copy the data from the new file to a file that is known to work
Accessing Excel Spreadsheet with C# occasionally returns blank value for some cells
Check out ABHI's answer in the above link (in particular points 1. and 2.)
I need to connect to an open Excel 2003 file using .NET 3.5
It seems the OleDb connection which I am trying to use wants the file exclusively. But I need to have this file open in Excel in the same time.
Is non-locking reading possible?
EDIT: I resolved this by copying file before opening it.
the question seems have no answer. and I cant delete it....
my solution was - run macro on timer to save the excel file in question and C# app was copying the file to another one and reading it using OleDb.
This seems like a similar problem:
Writing into excel file with OLEDB
Does that work out for you?
What parameters are you passing in when you open the Excel document? Could you set the "ReadOnly" parameter in Workbook.Open() to true? See here.
Refer to the code below how to get the information of Excel data into an array. Then you will perform any validations on that Excel sheet.
var fileName = #"D:\Pavan\WorkDiployed.xlsx";
var connectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0; data source={0}; Extended Properties=Excel 12.0;", fileName);
OleDbConnection con = new System.Data.OleDb.OleDbConnection(connectionString);
OleDbDataAdapter cmd = new System.Data.OleDb.OleDbDataAdapter("select * from [Sheet1$]", con);
con.Open();
System.Data.DataSet excelDataSet = new DataSet();
cmd.Fill(excelDataSet);
DataTable data = excelDataSet.Tables[0];
DataRow[] arrdata = data.Select();
foreach (DataRow rw in arrdata)
{
object[] cval = rw.ItemArray;
}
con.Close();
MessageBox.Show (excelDataSet.Tables[0].ToString ());