Writing table contents to xls from vb.net - asp.net

I have a program with an option to write db contents to an excel spreadsheet. This functionality is contained on a page called 'Search_aspx'.
Response.ClearContent()
Response.Charset = ""
Response.ContentType = "application/vnd.ms-excel"
Response.AddHeader("Content-Disposition", "attachment; filename=FileName.xls")
Response.Cache.SetCacheability(HttpCacheability.Private)
Dim dg As New DataGrid
dg.DataSource = dtResults
dg.DataBind()
Dim sw As New System.IO.StringWriter()
Dim htw As New HtmlTextWriter(sw)
dg.RenderControl(htw)
Response.Write(sw.ToString)
Response.Flush()
Response.Close()
This worked fine forever, but last week I migrated the solution to a new server (Server03 to Server08), and now it is not working. When I try to save, it asks if I want to "Save search_aspx" instead of "Save FileName.xls".
What is the issue here?
EDIT:
All righty... I took the advice posted below and followed Mason's suggestion, and the page still asks if I want to save 'Search_aspx'. Now have EPPlus installed in my solution, properly referenced etc....
Response.ClearContent()
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
Response.AddHeader("Content-Disposition", "attachment; filename=FileName.xlsx")
Dim package As New ExcelPackage()
Dim sheet = package.Workbook.Worksheets.Add("Data")
sheet.Cells.LoadFromDataTable(dtResults, False)
Response.BinaryWrite(package.GetAsByteArray())
Response.Flush()
Response.Close()

The real issue is you aren't creating an XLS file. You're creating an HTML file with a .xls extension. I discuss several reasons why that's a bad idea and go into detail about what you can do instead on my blog.
The short and sweet version is that there's no good way practice to generate a .xls file in an ASP.NET environment, and you should either generate .xlsx files with a decent library (discussed on my blog) or switch to another data format such as CSV.

Related

Download PDF in ASP Error on Some Machines

I am using this code to generate pdf's to download on an ASP page and the pdf does download properly on some pages but not on all. Several users are experiencing an error message as seen in the attached image. Please let me know if you have suggestions on how to fix this problem. It is sporadic so its been hard to nail down a cause.
Public Sub Download(filename As String)
Response.Clear()
Response.BufferOutput = False
Response.ContentType = "application/pdf"
Response.AddHeader("content-disposition", "attachment; filename=" + Path.GetFileName(filename))
Response.WriteFile(filename)
Response.Close()
End Sub
Try Response.Flush(), followed by Response.End().

Generating and downloading an `Excel` document breaks `ASP.net` LoginStatus

In my ASP.net web application I have a page which shows a (not very complicated) table. I have implemented a button so when the (registered) members clicks on it, the browser downloads the table as an Excel document
The code to generate this Excel is as follow:
Dim response As HttpResponse = HttpContext.Current.Response
' first let's clean up the response.object
response.Clear()
response.Charset = ""
Dim filename As String = MapPath("~/ex1.xls")
' set the response mime type for excel
response.ContentType = "application/vnd.ms-excel"
response.AddHeader("Content-Disposition", "attachment;filename=""" & filename & """")
' create a string writer
Using sw As New StringWriter()
Using htw As New HtmlTextWriter(sw)
' instantiate a datagrid
Dim dg As New DataGrid()
dg.DataSource = dt
dg.DataBind()
dg.RenderControl(htw)
response.Write(sw.ToString())
response.[End]()
End Using
End Using
The problem is that this code is breaking somehow the ASPN.net LoginStatus as when you try to log out after downloading this Excel (the "log out" buttom is always visible at the application) every click on the buttom will download the same Excelover and over (once per click). If you reload window or change page the "log out" will work again.
this is the "log out" link when inspecting it with chrome:
<a id="ctl00_ctl00_MainContent_LoginStatus1" href="javascript:__doPostBack('ctl00$ctl00$MainContent$LoginStatus1$ctl00','')">Log Out</a>
I have tried to make the Excel to download from other page using:
onclick="window.document.forms[0].target='_blank';"
and now it opens a new tab, download the Excel, close the tab (fast process) but still keeps breaking the logout link.
And I run out of ideas, any help, code, hint or whatever possible solution to fix this problem is very welcome.
Open a new page within the blank target, and let the new page generate the excel
This looks like a server side error.
Your code to logout actually runs the code to download Excel.
May be you should throw in a 'Response.End();' in the click handler for logout.
Well a quick work around would be to use report viewer control, which has an export to excel functionality.
I know this solution is not exactly what you were looking for, but from my experience when a user is looking for excel functionality, instead of providing a table/gridview results to the user i provide an rdlc report, which has all the export functionality.

Excel file showing aspx page after download from web folder

I am using the following code to download an excel file from my asp.net/vb.net website:
Dim msFilePath As String
Dim msFileName As String
msFilePath = Server.MapPath("~/Template.xls")
msFileName = msFilePath
Dim mAttachFileName As String = "Template.xls"
Response.Clear()
Response.ContentType = "application/vnd.ms-excel"
Response.AddHeader("Content-Disposition", "attachment; filename=""" & mAttachFileName & """")
Response.Flush()
The excel file is a template being provided with column headings and that is all it contains. When I click on the download button in my website it prompts me to save/open the file with the correct name 'Template.xls'. Once I open it is displaying the aspx page inside the excel file instead of the data that is supposed to be in the file and giving me an error saying it is missing the css file. I have debugged through and the path is pointing to the correct location of the file so I'm not sure what is causing the problem. Any help appreciated!!
I've had exactly the same problem, I'd like to tell why yours doesn't work but i'm not that smart. Instead i'll just tell you what code i've used that now works for me:
replace
Response.AddHeader("Content-Disposition", "attachment; filename=""" & mAttachFileName & """")
Response.Flush()
with
Response.AppendHeader("Content-Disposition", "attachment; filename=""" & mAttachFileName & """")
Response.TransmitFile(FilePath)
Response.End()
I know that response.End() is deprecated but without it I always get all that html garbage...
I suddenly started having the problem in my machine. I tried the application in other machines (web app) and it worked. I had to rule out coding issues at that point. I tried a million things and nothing worked. I rebooted the machine and voila...it worked.
Rebooting is always my last option, believe me.

VB ASP.Net Export to Excel: Name worksheet tab

Below is the method I'm using to export my gridview data to Excel. The user has asked if I can name the worksheet tab. Any ideas? Thanks in advance!
Private Sub btnExportToExcel_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnExportToExcel.Click
Dim form As New HtmlForm
Dim strAttachment As String
Dim stw As StringWriter
Dim htextw As HtmlTextWriter
stw = New StringWriter
strAttachment = "attachment; filename=" & strAppName & ".xls"
HttpContext.Current.Response.ClearContent()
HttpContext.Current.Response.AddHeader("content-disposition", strAttachment)
HttpContext.Current.Response.ContentType = "application/vnd.ms-excel"
htextw = New HtmlTextWriter(stw)
form.Controls.Add(CType(Session("gridViewControl"), Control))
Me.Controls.Add(form)
form.RenderControl(htextw)
Response.Write("<b>" & txtTitle.Text & "</b><br />")
Response.Write(stw.ToString())
Response.Flush()
Response.Close()
HttpContext.Current.ApplicationInstance.CompleteRequest()
End Sub
Its not possible because your output is really HTML with an HTML Table - which Excel will happily "parse"/translate into rows and columns (because that's what a table is). You're not really creating a "native" Excel file.
You can have more options (assuming all your clients do have Excel) by using Excel XML using native .Net (LINQ to XML, don't be scared by that term). I believe Excel XML support goes back to Office 2003 (maybe even Office XP/2002, but I could be wrong).
You can do so in C# or VB.net, but in VB.net it's almost trivial because of VB.Net's XML literals. See this MSDN video by Beth Massi for inspiration (magic starts around 5:00, but the entire video is worth every minute).
No, there is no way to be able to do that using this method. You would have to use a specialized library like Gembox to do this.
You can't do it via html, but you can do it via xml (SpreadsheetML). Take a look at the sample I posted in the answer here:
Generating an Excel file in ASP.NET

Error in file after download

I have word document which is opening perfectly at server but when i download it using button click event of my website it gets currept.
i am using below code on button click to make document download.
please help to resolve this problem:
i am using .net framework 3.5
Response.Clear();
Response.AddHeader("Content-Disposition", "attachment; filename=StandardLetter" + _responseId.ToString() + ".doc");
Response.ContentType = "application/octet-stream";
Response.TransmitFile (Server.MapPath("~/document/letter/StandardLetter" + _responseId.ToString() + ".doc"));
Do you have a Response.End() after that code you posted? If not, you will get extra "html" code from the aspx file added to the transmitted file - thus corrupting it.
EDIT
As Akshay Anand mentioned, a better way would be to call HttpContext.Current.ApplicationInstance.CompleteRequest(); instead of Response.End() see docs. See also this question.
Ok well here is the code I use, it's vb but easily converted ;)
Response.ContentType = "application/pdf"
Dim byteArray As Byte() = File.ReadAllBytes(MergedFile)
Response.AddHeader("Content-Disposition", "attachment;filename=""" & ShortFilename & """")
Response.AddHeader("Content-Length", byteArray.Length)
Response.BinaryWrite(byteArray)
Response.Flush()
Response.End()
This works for PDF and by changing .ContentType to Excel spits that out too.. So I assume this will take any MIME type. Good luck!
I take my pdf document called MergedFile and convert it to a byte(), I give it a 'ShortName' that can be entered by the user. Content-Length is very important..
Instead try:
Response.ContentType ="application/msword";
I dont use Word but for Excel I use:
Response.ContentType = "application/x-msexcel"

Resources