// I want to use the SQL Query SELECT * FROM Table here, how can I do that?
string filepath = Server.MapPath("test.doc");
FileInfo file = new FileInfo(filepath);
// Checking if file exists
if (file.Exists)
{
// Clear the content of the response
Response.ClearContent();
// LINE1: Add the file name and attachment, which will force the open/cance/save dialog to show, to the header
Response.AddHeader("Content-Disposition", "attachment; filename=" + file.Name);
// Add the file size into the response header
Response.AddHeader("Content-Length", file.Length.ToString());
// Set the ContentType
Response.ContentType = ReturnExtension(file.Extension.ToLower());
// Write the file into the response (TransmitFile is for ASP.NET 2.0. In ASP.NET 1.1 you have to use WriteFile instead)
Response.TransmitFile(file.FullName);
// End the response
Response.End();
}
Can anyone help me with getting the contents of the table called Table in SQL Server 2008 and downloading it? I have the codes above, but currently it reads from a path, how to make it read from a SELECT query? The query in mind is "SELECT* FROM Table"
One way is to use a SQLDataReader (I'm not going to explain connections etc too here: I assume you've called a database before) and manually concatenate the columns
You'd normally use bcp.exe or perhaps SMO for this.
You could use SqlDataAdapter to fetch the data and populate a DataTable based on the data:
SqlConnection connection = new SqlConnection(connectionString);
string query = "SELECT * FROM Table";
SqlDataAdapter adapter = new SqlDataAdapter(query, connection);
connection.Open();
DataTable table = new DataTable();
try
{
adapter.Fill(table);
}
catch (Exception e)
{
throw e;
}
finally
{
connection.Close();
}
}
Related
I'm trying to read an ".xlsx" file using an OleDbDataAdapter. Please read until the end of the post before answering. Here is the code I'm using:
private DataTable ExtractDataFromFile(string fileName)
{
DataTable sheetData = new DataTable();
using (OleDbConnection conn = this.returnConnection(fileName))
{
try{
conn.Open();
OleDbDataAdapter sheetAdapter = new OleDbDataAdapter("select * from [Sheet1$]", conn);
sheetAdapter.Fill(sheetData);
}
catch(Exception e)
{
Console.WriteLine(e);
Console.ReadLine();
}
}
return sheetData;
}
private OleDbConnection returnConnection(string fileName)
{
return new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileName + ";Extended Properties=Excel 12.0;");
}
But I'm getting a peculiar error. The Excel files I have to query have been given to me by a client, and I get the following error when I try to open them
External table is not in the expected format
Here is the catch:
I've noticed that if I open one of the Excel files and manually save it once and close the file, then I can query the file with my program!
Are you sure, you have create the xlsx file using Microsoft office? This file could be an open xml document, but maybe not created by MS Office, so the MS oledbadapter cannot read it. If you open and save it then it probably converts it to MS version of open xml and then oledbadapter can read it.
You can look into DocumentFormat.OpenXml to read xlsx files.
Using ASP.NET web page, I am exporting some data to excel spreadsheet (XLSX). The code is running fine when I run it using Visual Studio (it is exporting a XLSX file with correct data), but the same code fails when deployed to Testing Server.
It is not throwing any error, it simply exports a blank XLSX file.
Note: While debugging in the test server, I found that the data is getting fetched and temp file is also getting created properly, but the data is not getting written to the temp file (the weird thing is it doesn't through any error).
Added later
After doing some more research, I have found that there is no issue with small record set (say 1000, 2000). But when tried with ~20K records, I get a blank file.
I have been burning myself for last 2 days, someone rescue me :) ...
Code
string templateFile = #"C:\Templates\ExportFile.xlsx";
string tempFileName = Path.Combine(#"C:\Temp\", Path.GetRandomFileName());
tempFileName = Path.ChangeExtension(tempFileName, ".xlsx");
File.Copy(templateFile, tempFileName);
List<Customer> customerList = FetchCustomers();
DataTable dataTableObj = new DataTable("Customers$");
dataTableObj.Columns.Add(new DataColumn("CustomerID"));
dataTableObj.Columns.Add(new DataColumn("FirstName"));
dataTableObj.Columns.Add(new DataColumn("LastName"));
dataTableObj.Columns.Add(new DataColumn("CreatedDate"));
foreach (Customer customerObj in customerList)
{
DataRow dataRowObj = dataTableObj.NewRow();
dataRowObj["CustomerID"] = customerObj.CustomerID;
dataRowObj["FirstName"] = customerObj.FirstName;
dataRowObj["LastName"] = customerObj.LastName;
dataRowObj["CreatedDate"] = customerObj.CreatedDate;
dataTableObj.Rows.Add(dataRowObj);
}
using (OleDbConnection oleDbConnectionObj = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + tempFileName + ";Extended Properties=\"Excel 12.0 Xml;HDR=YES;\""))
{
OleDbCommand insertCommand = new OleDbCommand();
insertCommand.Connection = oleDbConnectionObj;
insertCommand.CommandText = #"INSERT INTO [Customers$] ([CustomerID], [FirstName], [LastName], [CreatedDate]) VALUES (?, ?, ?, ?)";
insertCommand.Parameters.Add("CustomerID", OleDbType.Numeric, 0, "CustomerID");
insertCommand.Parameters.Add("FirstName", OleDbType.VarChar, 0, "FirstName");
insertCommand.Parameters.Add("LastName", OleDbType.VarChar, 0, "LastName");
insertCommand.Parameters.Add("CreatedDate", OleDbType.Date, 0, "CreatedDate");
DataSet dataSetObj = new DataSet();
dataSetObj.Tables.Add(dataTableObj);
OleDbDataAdapter dataAdapter = new OleDbDataAdapter();
dataAdapter.InsertCommand = insertCommand;
dataAdapter.Update(dataSetObj, "Customers$");
}
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/vnd.ms-excel";
Response.Charset = "";
Response.AddHeader("Content-Disposition", "attachment; filename=Customers.xlsx");
Response.WriteFile(tempFileName);
Response.Flush();
Response.End();
Finally it got resolved!!!
While creating large XLSX file (greater then ~1MB), OLEDB Provider tries to create temp file at Local Settings\Temporary Internet Files\Content.MSO\ for the APP POOL account. If the folder doesn't exists or the APP POOL account doesn't have proper permission, then it fails without throwing errors (no idea why it doesn't throw error).
In my case Content.MSO folder was missing at C:\Documents and Settings\Default User\Local Settings\Temporary Internet Files.
I created the folder and gave the modify permission to NETWORK SERVICES..... and "Voila!" - everything started working.
Thanks to the below 2 links, they saved me days...:)
Microsoft ACE OLEDB connection creating empty Excel when there are 166,110 rows
http://www.rapidsnail.com/developer/topic/2011/109/2/65194/excel-writes-secret-use-oledb-write-data-to-excel-more-than-13571-line-file-for-blank.aspx
I'm using this function to create an Excel file from my SQL Server query
DataTable dt = new DataTable();
SqlConnection objcon = new SqlConnection(connectionString);
string sql = "My SELECT SQL";
SqlDataAdapter objda = new SqlDataAdapter(sql, objcon);
objda.Fill(dt);
GridView gvreport = new GridView();
gvreport.DataSource = dt;
gvreport.DataBind();
string fileName = string.Format("fileNameHere");
Response.ClearContent();
Response.AddHeader("content-disposition", "attachment; filename=" + fileName);
Response.ContentType = "application/excel";
System.IO.StringWriter sw = new System.IO.StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
gvreport.RenderControl(htw);
Response.Write(sw.ToString());
Response.End();
return null;
Which worked great until I now realized that it does not work so well when its trying to write over 11,000 rows.
The Excel file itself is fine but after around 11,000 rows it suddenly breaks during one and after that all rows are blank. The rows themselves are still "created" with an border and everything but they are all blank.
Any idea what is causing this? Or is there any better way to create an Excel file like this?
Well, in your case you are not actually generating a real Excel file, just plain HTML and telling Excel to open it and convert it. You may encounter other problems using this approach with OpenOffice or LibreOffice or any other tool that actually expects a real Excel file.
I would look into a more robust solution, by using either OpenXml directly, or indirectly through ClosedXml or some other similar component.
For example, if you were to use ClosedXml, you can do something like this:
var wb = new XLWorkbook();
var dataTable = GetTable("Information");
// Add a DataTable as a worksheet
wb.Worksheets.Add(dataTable);
wb.SaveAs("AddingDataTableAsWorksheet.xlsx");
Extracted from: https://closedxml.codeplex.com/wikipage?title=Adding%20DataTable%20as%20Worksheet
However, in your case instead of saving to a physical file you'd output the stream directly to the Response.
I have got a page in which there is a file upload option where I have to upload/import the csv file. What I want to do is to check if the correct format of file is uploaded for instance if any other than csv file is uploaded, the system should give an error message. Also what I need to do is to check certain fields of the csv file for instance there are some mandatory fields in the csv file which should be there like name , postcode, How can I check that these fields are not empty . After performing these task, the system should automatically upload the csv file onto the sql sever 2008. Any ideas or tutorial ... will be highly appreciated.
Check out this thread:
Parsing CSV files in C#, with header
I believe this will let you extract it as you want and then easily shove it into a table in SQL Server.
try using Oledb. this codesnippet helps you read your csv file into a datatable which should be pretty easy to dump to a database.
public static DataTable ParseCSV(string path)
{
if (!File.Exists(path))
return null;
string full = Path.GetFullPath(path);
string file = Path.GetFileName(full);
string dir = Path.GetDirectoryName(full);
//create the "database" connection string
string connString = "Provider=Microsoft.Jet.OLEDB.4.0;"
+ "Data Source=\"" + dir + "\\\";"
+ "Extended Properties=\"text;HDR=No;FMT=Delimited\"";
//create the database query
string query = "SELECT * FROM " + file;
//create a DataTable to hold the query results
DataTable dTable = new DataTable();
//create an OleDbDataAdapter to execute the query
OleDbDataAdapter dAdapter = new OleDbDataAdapter(query, connString);
try
{
//fill the DataTable
dAdapter.Fill(dTable);
}
catch (InvalidOperationException /*e*/)
{ }
dAdapter.Dispose();
return dTable;
}
Check out the fast CSV reader over at codeproject.com
Another option would be to use SSIS.
i got a page users downloading files from there.And when a user click download link and finish downloading file , i am insertin' a new record for my File Download Counter event. (FileID,Date,blalbla..)
But there is problem with my script ... after download starts and finish, its adding a new record but after this, its fires event again and making a new record too.So 1 download and 2 new download record. here is my script;
if (Page.Request.QueryString["FileID"] != null)
{
OleDbCommand command = new OleDbCommand("select * from Dosyalar where DosyaID=" + Page.Request.QueryString["FileID"].ToString(), veri.baglan());
string dosyaAdi = "";
int DosyaID = 0;
OleDbDataReader dr = command.ExecuteReader();
while (dr.Read())
{
dosyaAdi = Server.MapPath("formlar") + "\\" + dr["URL"].ToString();
DosyaID = Convert.ToInt32(dr["FileID"]);
}
dr.Close();
FileInfo dosya = new FileInfo(dosyaAdi);
Response.Clear();
Response.AddHeader("Content-Disposition", "attachment; filename=" + dosya.Name);
Response.AddHeader("Content-Length", dosya.Length.ToString());
Response.ContentType = "application/octet-stream";
Response.WriteFile(dosyaAdi);
// INSERT A NEW RECORD
OleDbCommand ekle = new OleDbCommand("Insert into Indirilenler (FileID,Tarih) values (#p1,#p2)", veri.baglan());
ekle.Parameters.AddWithValue("p1", FileID);
ekle.Parameters.AddWithValue("p2", DateTime.Now.ToShortDateString());
ekle.ExecuteNonQuery();
Response.Flush();
Response.End();
The problem is that the browser is actually making two requests to get the file. This is typical behaviour.
Either you can turn OutputCaching on this page on. This should mean that the browser's second request won't hit your server, and thus only record one entry, but you also need to make sure that you don't have the debug flag set in your web.config file.
The other option is to detect the request type. I think that the first request the browser sends is often a HEAD request and not a GET, or POST. You could detect and handle these appropriately but I think the first option maybe more reliable.
Also, you should really be coding this as a ASPX Handler not a page. This means you could avoid the response.Clear() and thus you don't confuse the browser as to what the content type of the URI is.