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
Related
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.
I am new to crystal reports. I have been having this problem for quite some time and can't seem to solve it. What I am doing is running a report and sending back the generated PDF in the response.
The problem is, when I run the asp.net page (which runs the report) from the browser it works fine for the first or second time but then after that, the browser just keeps waiting and I do not get any response back from the server, not even an error! It just keeps loading for a long time. I even did a clean re-install of the server but still have the same issue. I was not having this problem during initial testing of this page.
Crystal reports is being unpredictable and I am not sure if this is because the reports are not being closed properly or the connection is not proper.
Windows Server 2003 - IIS
Here is the vb.net page -
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim connectionInfo As New ConnectionInfo
connectionInfo.ServerName = "UID=abc;PWD=abc;Driver= {SQL Server};Server=" & Page.Request.QueryString("server") & ";Database=" & Page.Request.QueryString("database")
Using report As New ReportDocument
report.Load(Server.MapPath("/report/Crystal/test.rpt"))
report.FileName = Server.MapPath("/report/Crystal/test.rpt")
SetDBLogonForReport(connectionInfo, report)
report.SetParameterValue("param1", Page.Request.QueryString("param1"))
Dim oStream As New MemoryStream()
oStream = report.ExportToStream(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat)
Response.Clear()
Response.Buffer = True
Response.ContentType = "application/pdf"
Response.BinaryWrite(oStream.ToArray())
report.Close()
End Using
Response.Flush()
Response.End()
End Sub
Private Sub SetDBLogonForReport(ByVal connectionInfo As ConnectionInfo, ByVal reportDocument As ReportDocument)
Dim tables As Tables
tables = reportDocument.Database.Tables
For Each table As CrystalDecisions.CrystalReports.Engine.Table In tables
Dim tableLogonInfo As New TableLogOnInfo
tableLogonInfo = table.LogOnInfo
tableLogonInfo.ConnectionInfo = connectionInfo
table.ApplyLogOnInfo(tableLogonInfo)
Next
End Sub
</div>
</form>
First off, put the call to report connection in the Page_Init() event, not Page_Load(). Prior to .NET 2005 it was okay to put it in Page_Load(). But now they changed how memory is managed and this can give you random errors depending upon the state of the CrystalReportViewer's memory. Putting it in Page_Init() is safe all the time.
Secondly, I would do is remove the code:
CrystalReportViewer1.DataBind();
I would also remove the RefreshReport() call b/c it refreshes itself automatically when you assign the report object to it. But it doesn't hurt to have it. Either way, definitely get rid of the .DataBind() call.
Hopefully these changes will get your application back to working.
For more detail Please check below link I face same problem year ago. Hope it's helpful
LInk
I am busy creating a control in asp.net. The control consists of some text and an image. The image will be used to display a graph. The control gets the data for the graph by reading it from a database. It seems I have two options to display the graph in the image box. First, I can create a jpg from the data and save the file on the server. I can then load this file into the image box. I think this would cause a problem if various users try to access the site at the same time, so I don't think it is a good option. The other options is to create a file called output, that outputs the graph like this: objBitmap.Save(Response.OutputStream, ImageFormat.Gif)
I can then display the image like this in my control: Image1.ImageUrl = "output.aspx"
The problem that I am facing is how do I get the data from my control to the output page? As far as I know it is too much data to pass as a parameter. If there is another better method of doing it, please let me know
Thanks
You can write the image content to the response of output.aspx. Something like this (taken from one of my existing GetImage pages:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim strFilename As String
strFilename = Request.QueryString("filename")
Dim strPath As String = AppSettings("ProxyImageSavePath") & strFilename
Response.Clear()
Response.ContentType = "image/jpeg"
If Not IO.File.Exists(strPath) Then
'erm
Response.Write("file not found")
Else
Response.WriteFile(strPath)
End If
Response.End()
End Sub
Edit: I've just realised this may not be the solution you're looking for; Your webserver should be able to cache this though.
You need handlers. See in this article, Protecting Your Images, section "Creating the ImageHandler HTTP Handler", you'll find the code how to write the handler, so it outputs an image. You don't need all, it's only an example.
You also need to register the handler in the web.config.
To reference it Image1.ImageUrl = "handler.ashx?graphdata=xxxx". Use QueryString to get the data source to generate the graph.
Howdy, Now I'm a complete newby to .Net and the likes of VB (I'm more of a Ruby/Rails, PHP kinda guy).
Anyway I currently have a sub that has a string builder that I'm wish to use as the content of a CSV which I will email later from a webpage. My stringbuilder is creating the content for the CSV but I don't know how to create the CSV dynamically (I don't want the CSV on disk).
Private Shared Sub BuildClientTrustBalanceCSV(ByVal sb As StringBuilder, ByVal clientsWithTrustBalance As List(Of NonPaymentHistory))
If clientsWithTrustBalance Is Nothing OrElse clientsWithTrustBalance.Count = 0 Then
Exit Sub
End If
' need to somewhere create the CSV then inject the StringBuilder into it?
With sb
' create the CSV
For Each zeroBalanceClient As NonPaymentHistory In clientsWithTrustBalance
.AppendFormatLine("{0},", zeroBalanceClient.Number)
Next zeroBalanceClient
End With
End Sub
Any ideas? I know I should be able to sort this but .NET just isn't my thing?
Here is a link that might be helpful, but I agree with Oded that the question is misleading.
How do I best generate a CSV (comma-delimited text file) for download with ASP.NET?
Very odd problem as this is working perfectly on our old Classic ASP site. We are basically querying the database and exporting around 2200 lines of text to a Text File through Response.Write to be output to a dialog box and allows the user to save the file.
Response.Clear()
Response.ClearContent()
Response.ClearHeaders()
Dim fileName As String = "TECH" & test & ".txt"
Response.AddHeader("Content-Disposition", String.Format("attachment; filename={0}", fileName))
Response.ContentType = "text/plain"
Response.Write(strHeader)
Dim sw As New IO.StringWriter()
Dim dtRow As DataRow
For Each dtRow In dt3.Rows
sw.Write(dtRow.Item("RECORD") & vbCrLf)
Next
Response.Write(sw.ToString)
Response.Write(strTrailer & intRecCount)
Response.End()
I can either use StringWriter or simply use Response.Write(dt.Rows(i).Item("RECORD").toString
Either way, the Export is causing a horrendous hang on our development site. My local machine causes no hang and is almost instantaneous. The recordset isn't very large, and the lines it is writing are small.
Anyone have any idea why this would be hanging? It does EVENTUALLY allow for a save and display the file, but it's well over 3-4 minutes.
Attach a remote debugger and find where its hanging?
You need to figure out if its the string writer loop, or the actual query code (which is not provided here).
Sounds like maybe you're overflowing the output buffer. Perhaps add a counter in there to flush every few hundred lines.
Also, the Response object basically does most of the work for a StringWriter for you. Using the StringWriter as an intermediary is probably redundant.
Both using StringWriter and DataTable are overkill.
Why not use directly SqlReader to get the results from the database, and while reading the reader, write directly to the output stream? Much faster, and much less memory consumed.
As an answer to your second question - why the ASP was working OK, I doubt that there you have stored the same content 3 times in memory in order to output it (in the DataTable, in the StringWriter and in the output buffer). My ASP is a little bit rusty, but I would guess that there you are using database reader of some sort.
Also, better employ some logging infrastructure (NLog, log4net), so you can output some timing about which operation delays how much, as an alternative to attaching a remote debugger.