Export DataTable to Excel from VB.Net - asp.net

The following code is my current attempt at opening some data in excel from a website button in VB.Net. I would like the data to show up barebones, but the formatting from the table on the website always follows. The paging and colors make the data near impossible to read and can only see the first page of data. Any quick fixes? I've tried a lot of things I've found on here but to no avail.
Private Sub DownloadExcel()
Response.Clear()
'Dim dt As DataTable = TryCast(ViewState("GridData"), DataTable)
Grid_Bad_Meters.AllowPaging = False
Grid_Bad_Meters.AllowSorting = False
'Grid_Bad_Meters.DataSource = dt
'Grid_Bad_Meters.DataBind()
Dim sfile As String = "Communication_Failures" & Now.Ticks
Response.AddHeader("content-disposition", "attachment;filename=" & sfile & ".xls")
Response.Charset = ""
' If you want the option to open the Excel file without saving then
' comment out the line below
' Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.ContentType = "application/vnd.ms-excel"
Dim stringWrite As New System.IO.StringWriter()
Dim htmlWrite As System.Web.UI.HtmlTextWriter = New HtmlTextWriter(stringWrite)
Grid_Bad_Meters.RenderControl(htmlWrite)
Response.Write(stringWrite.ToString())
Response.End()
'Grid_Bad_Meters.AllowPaging = True
'Grid_Bad_Meters.AllowSorting = True
'GridView1.DataSource = dt
'GridView1.DataBind()
End Sub

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Try
Dim ScriptManager As ScriptManager = ScriptManager.GetCurrent(Me.Page)
ScriptManager.RegisterPostBackControl(Me.btnExportToExcel)
Catch ex As Exception
End Try
End Sub
Protected Sub btnExportToExcel_Click(sender As Object, e As EventArgs) Handles btnExportToExcel.Click
Try
Dim sw As New System.IO.StringWriter()
Dim hw As New System.Web.UI.HtmlTextWriter(sw)
Dim style As String = "<style>.textmode{mso-number-format:\#;}</style>"
Response.Clear()
Response.Buffer = True
Response.AddHeader("content-disposition", "attachment;filename=SignExport.xls")
Response.Charset = ""
Response.ContentType = "application/vnd.ms-excel"
For i As Integer = 0 To Me.Grid_Bad_Meters.Rows.Count - 1
Dim row As GridViewRow = Grid_Bad_Meters.Rows(i)
row.Attributes.Add("class", "textmode")
Next
'lblRptHeader.RenderControl(hw)
hw.WriteBreak()
'lblReportDateRange.RenderControl(hw)
Grid_Bad_Meters.RenderControl(hw)
Response.Write(style)
Response.Output.Write(sw.ToString())
Response.Flush()
Response.End()
Catch ex As Exception
End Try
End Sub

You could use one of the two approaches mentioned below. Of course, there are other ways of meeting your requirement like exporting to csv file as mentioned in a comment or using a .Net library meant for Excel exporting like epplus.
OpenXML Approach
If you are looking for a way to export to Excel without using the html approach, then you can use OpenXML approach that is explained very clearly with a working example at this URL: Export to Excel using OpenXML. This will eliminate all the CSS styles that can get associated with exporting using html approach and you seem to be using this html approach according to the code in your original post. However, if you want to use the html approach, then the code below should work and eliminate all CSS styles that can come in the way when viewing the excel file. I have actually tried this posted code on my machine before putting it here.
Html Approach
You can create a new instance of GridView in your export method rather than use an existing instance, and data bind it to same data as the existing gridview on your page before rendering it to excel. Before you data bind it in the export method you need to make sure that no styles are set and specifically the grid line are set to none as in code below.
You can see an actual video of how this works at this URL : Grid Export without any CSS Styles. This was how the code behaved on my laptop when I ran it.
You can use sample code below, but make sure the data source is set to data that includes all records across all pages of original gridview. I have used SqlDataSource1 as data source but you can replace it by an appropriate method in your situation.
Protected Sub btnExport_Click(sender As Object, e As EventArgs)
Dim GridView2 As New GridView()
GridView2.AllowPaging = False
GridView2.AllowSorting = False
GridView2.Style.Clear()
GridView2.CellPadding = 0
GridView2.CellSpacing = 0
GridView2.GridLines = GridLines.None
GridView2.BorderStyle = BorderStyle.None
GridView2.BorderWidth = Unit.Pixel(0)
GridView2.AlternatingRowStyle.BorderStyle = BorderStyle.None
GridView2.DataSource = SqlDataSource1
GridView2.DataBind()
' Clear the response
Response.Clear()
' Set the type and filename
Response.AddHeader("content-disposition", "attachment;filename=griddata.xls")
Response.Charset = ""
Response.ContentType = "application/vnd.xls"
' Add the HTML from the GridView to a StringWriter so we can write it out later
Dim sw As New System.IO.StringWriter()
Dim hw As System.Web.UI.HtmlTextWriter = New HtmlTextWriter(sw)
GridView2.RenderControl(hw)
' Write out the data
Response.Write(sw.ToString())
Response.[End]()
End Sub
Public Overrides Property EnableEventValidation() As Boolean
Get
Return False
End Get
'Do nothing
Set
End Set
End Property
Public Overrides Sub VerifyRenderingInServerForm(control As Control)
'Allows for printing
End Sub

Related

Simple export from ASP.NET GridView into Excel VB.NET

I have a GridView that I need to export into Excel (by button event) and I'm using Visual Studio and vb.net.
I never tried this before and I'm kinda clueless, is there a simple way to do this? I don't think I need any complications at the moment, just a simple export of the GridView information.
Also I already got a connection between the GridView and my database. I tried adding a working Excel export from other project but I still miss something .
Public Overrides Sub VerifyRenderingInServerForm(ByVal control As Control)
' Verifies that the control is rendered
End Sub
Protected Sub exportExelBtn_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles exportExelBtn.Click
Dim errorCheck As Integer = 0
Dim popupscript As String = ""
If approvalGrid.Rows.Count > 0 Then
Try
Response.ClearContent()
Response.Buffer = True
Response.AddHeader("content-disposition", String.Format("attachment; filename={0}", "TestPage.xls"))
Response.ContentEncoding = Encoding.UTF8
Response.ContentType = "application/ms-excel"
' Dim sw As New stringwriter()
Dim tw As New IO.StringWriter()
Dim htw As New HtmlTextWriter(tw)
approvalGrid.RenderControl(htw)
Response.Write(tw.ToString())
Response.[End]()
Catch ex As Exception
errorCheck = 1
End Try
Else
errorCheck = 1
End If
If errorCheck = 1 Then
'a pop up error messege feature
popupscript = "<script language='javascript'>" + "alert(" + Chr(34) + "There was an error in exporting to exel, please make sure there is a grid to export!" + Chr(34) + ");</script>"
End If
Page.ClientScript.RegisterStartupScript(Me.GetType(), "PopUpWindow", popupscript, False)
End Sub
The problem is that the file that it creates upon click says it's not Excel format and when I agree to open it I do see the GridView information as I wanted but I also see a lot of extra info in the form of buttons calanders and other stuff from my page, how can I prevent the export of those other stuff?
Please Try Below code
Public Overrides Sub VerifyRenderingInServerForm(control As Control)
' Verifies that the control is rendered
End Sub
Protected Sub btnExport_Click(sender As Object, e As EventArgs)
If gridview.Rows.Count > 0 Then
Try
gridview.Columns(0).Visible = False
Response.ClearContent()
Response.Buffer = True
Response.AddHeader("content-disposition", String.Format("attachment; filename={0}", "TestPage.xls"))
Response.ContentEncoding = Encoding.UTF8
Response.ContentType = "application/ms-excel"
Dim sw As New StringWriter()
Dim htw As New HtmlTextWriter(sw)
gridview.RenderControl(htw)
Response.Write(sw.ToString())
Response.[End]()
Catch ex As Exception
Finally
gridview.Columns(0).Visible = True
End Try
End If
End Sub
I have written above code to export gridview to excel file, it exports successfully but there are some content in gridview in Persian language which is shown unreadable in exported excel file. the code I have written is as below:
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If GridView1.Rows.Count > 0 Then
Response.ClearContent()
Response.Buffer = True
Response.AddHeader("content-disposition", String.Format("attachment; filename={0}", "IncentiveReport.xls"))
Response.ContentEncoding = Encoding.UTF8
Response.ContentType = "application/ms-excel"
Dim sw As New IO.StringWriter()
Dim htw As New HtmlTextWriter(sw)
GridView1.RenderControl(htw)
Response.Write(sw.ToString())
Response.End()
End If
End Sub
Public Overrides Sub VerifyRenderingInServerForm(control As Control)
' Verifies that the control is rendered
End Sub

System.OutOfMemoryException when exporting GridView to Excel

I have a sub that exports a ASP Gridview to excel, it works fine, however, when there are a large amount of rows I get this error:
Exception of type 'System.OutOfMemoryException' was thrown.
Any ideas how to solve this? Here is my export to excel sub:
Protected Sub btnExportMonthlyUK_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnExportMonth.Click
Dim title As String
title = "MonthlyReportUK"
Response.Clear()
Response.AddHeader("content-disposition", String.Format("attachment;filename={0}.xls", title))
Response.Charset = ""
Response.ContentType = "application/vnd.xls"
Response.ContentEncoding = Encoding.Unicode
Response.BinaryWrite(Encoding.Unicode.GetPreamble())
Dim strWr As New StringWriter()
Dim HtmlWr As New HtmlTextWriter(strWr)
monthlyReportsIE.AllowPaging = False
monthlyReportsIE.DataBind()
monthlyReportsIE.RenderControl(HtmlWr)
Response.Write(strWr.ToString())
Response.End()
End Sub
You can try rendering the control directly to the output stream by using a StreamWriter and avoid creating a large string in memory. You can also try setting Response.Buffer to False and the server will send the output to the client directly as it is processed.
Protected Sub btnExportMonthlyUK_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnExportMonth.Click
Dim title As String
title = "MonthlyReportUK"
Response.Clear()
Response.AddHeader("content-disposition", String.Format("attachment;filename={0}.xls", title))
Response.Charset = ""
Response.ContentType = "application/vnd.xls"
Response.ContentEncoding = Encoding.Unicode
Response.BinaryWrite(Encoding.Unicode.GetPreamble())
Response.Buffer = False
monthlyReportsIE.AllowPaging = False
monthlyReportsIE.DataBind()
Using strWr As new StreamWriter(response.OutputStream)
Using htmlWr As new HtmlTextWriter(strWr)
monthlyReportsIE.RenderControl(htmlWr)
End Using
End Using
Response.End()
End Sub
If this answer is not valid in your case, then you should consider an external library to do the job, because exporting large Excel files as HTML is memory consuming.
Check this sample about how to export the datatable of gridview.

How to export a datasource's selected data to excel?

I am using the code below which will export the gridview to an excel sheet. Problem is it will only export the records/columns on the page (10 of them) because my gridview setting is set to only show 10 rows per page and only certain columns. Is there a way I can export all records and columns from a datasource to excel?
Protected Sub ImageButton1_Click(sender As Object, e As System.Web.UI.ImageClickEventArgs) Handles ImageButton1.Click
Response.Clear()
Response.Buffer = True
Response.ContentType = "application/vnd.ms-excel"
Response.Charset = ""
Me.EnableViewState = False
Dim oStringWriter As New System.IO.StringWriter
Dim oHtmlTextWriter As New System.Web.UI.HtmlTextWriter(oStringWriter)
GridView1.RenderControl(oHtmlTextWriter)
Response.Write(oStringWriter.ToString())
Response.[End]()
End Sub
When I instituted database-level paging, I had to create a separate "Export" page that would render all of the data without paging into a separate GridView. Then I called the function you have in your question to render it. I suggest you do it that way.

String Format when Export to Excel From gridview

I Have export Gridview data to excel, here's my code :
Protected Sub btnExport_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnExport.Click
Try
Dim dt As New DataTable
If CReversal.SearchReversal2(txtAccount.Text, txtCustName.Text, txtAmount.Text, dropResponse.SelectedValue.ToString, txtRefNo.Text, txtDate.Text) Then
dt = CReversal.DT
Else
eMessage("System failure: ", CReversal.eMsg)
End If
Dim DataGrd As New DataGrid()
DataGrd.DataSource = dt.DefaultView
DataGrd.DataBind()
Dim attachment As String
attachment = "attachment; filename=Inquiry_Report" & Format(Now, "ddMMMyyyy") & ".xls"
Response.Buffer = True
Response.ClearContent()
Response.ClearHeaders()
Response.AddHeader("content-disposition", attachment)
Response.ContentType = "application/ms-excel"
Dim sw As New StringWriter()
Dim htw As New HtmlTextWriter(sw)
DataGrd.RenderControl(htw)
Response.Write(sw.ToString())
Response.End()
Catch ex As Exception
eMessage("Export Data failure: ", ex.ToString())
End Try
End Sub
the export process is run as i want. but when i open the excel file, i got some strings number character become like this :
but actually the datagridvie display is like this :
is it possible to format the string number character when we want to export to excel programatically? thk you
The problem with your approach is, that you are not writing "real" excel data. It is a html table which CAN be read by excel, but you are not really able to influence the way excel reads this mess. Libraries like EPPLus are much better at writing excel file and reduce your headaches by orders of magnitude. It is free, even in commercial contexts, so no problems when you use it. Just better results
As a side note: Epplus supports a "LoadFromDataTable" method- with a little luck, that all you need...

Exporting datatable to excel file with save dialog

I have a datatable being created with various inputs. Sometimes the resulting table is 35000+ rows. Currently, the datatable gets displayed onto a gridview. It loads fine after a couple minutes. Then, theres an option to export the gridview to an excel file. Everytime we have a large table to export, the conversion fails.
My goal is to bypass the gridview step and take the formatted table and put it directly into an excel file. Could also be a csv file if thats faster to write/load, as long as the data table is similar to the gridview output.
I tried the following code here Export DataTable to Excel File. I did my best to convert it to vb, here...
Protected Sub btnExportData_Click(sender As Object, e As EventArgs) Handles btnExportData.Click
Dim dt As DataTable
dt = CreateDataSource()
Dim filename As String = "attachment; filename=DistComplain.xls"
Response.ClearContent()
Response.AddHeader("content-disposition", filename)
Response.ContentType = "application/vnd.ms-excel"
Dim tab As String = ""
For Each dc As DataColumn In dt.Columns
Response.Write((tab + dc.ColumnName))
tab = "" & vbTab
Next
Response.Write("" & vbLf)
Dim i As Integer
For Each dr As DataRow In dt.Rows
tab = ""
i = 0
Do While (i < dt.Columns.Count)
Response.Write((tab + dr(i).ToString))
tab = "" & vbTab
i = (i + 1)
Loop
Response.Write("" & vbLf)
Next
Response.End()
End Sub
CreateDataSource() is the table that gets created in memory. Then theres other buttons that call it to fill the gridview. Right now it successfully complies and runs, and then it successfully creates the file. Although, when the file tries to open I get this error...
This happens when I try both xls and csv files. Something is not getting translated right. Any solutions?
(Written with help from Google) Create an export using the StringWriter class:
Public Shared Sub ExportDataSetToExcel(ds As DataSet, filename As String)
Dim response As HttpResponse = HttpContext.Current.Response
'Clean response object
response.Clear()
response.Charset = ""
'Set response header
response.ContentType = "application/vnd.ms-excel"
response.AddHeader("Content-Disposition", "attachment;filename=""" & filename & """")
'Create StringWriter and use to create CSV
Using sw As New StringWriter()
Using htw As New HtmlTextWriter(sw)
'Instantiate DataGrid
Dim dg As New DataGrid()
dg.DataSource = ds.Tables(0)
dg.DataBind()
dg.RenderControl(htw)
response.Write(sw.ToString())
response.[End]()
End Using
End Using
End Sub
You just need to pass the function the DataSet and the File Name. If you do not want to edit your CreateDataSource() function, you can merge it into a DataSet first like so:
Dim dt As DataTable = CreateDataSource()
Dim ds As New DataSet
ds.Merge(dt)
Your question is about why you're getting the message about being unable to open the file, correct?
According to Microsoft, this occurs when you have the "Ignore other applications that use Dynamic Data Exchange (DDE)" setting turned on. (See here). The link includes instructions to change the setting.

Resources