如何在vb.net中将datagrid保存为excel?
时间:2020-03-05 18:43:07 来源:igfitidea点击:
我知道这应该很容易,但是如何导出/保存DataGridView以使其出色呢?
解决方案
回答
是否需要是本机XLS文件?最好的选择就是将数据导出到CSV文件,该文件是纯文本格式,并且很容易生成。默认情况下,大多数用户会在Excel中打开CSV,因此他们不会知道两者之间的区别。
回答
在这里,我们使用一些代码在许多应用程序中执行此操作。我们有一种特殊的方法来清理"不可导出"列。此外,我们不会导出没有标题的cols,但是我们可以根据需要调整该逻辑。
编辑:代码格式化程序不喜欢vb.net,我们可以将其复制/粘贴到Visual Studio中,这会很好。
Public Overloads Shared Function BuildExcel(ByVal gView As System.Web.UI.WebControls.GridView) As String PrepareGridViewForExport(gView) Dim excelDoc As New StringBuilder Dim startExcelXML As String = " " + _ " " + _ " " + _ " " + _ " " + _ " " + _ " " + _ " " + _ " " Dim endExcelXML As String = "" Dim rowCount As Int64 = 0 Dim sheetCount As Int16 = 1 excelDoc.Append(startExcelXML) excelDoc.Append("") excelDoc.Append("") ' write out column headers excelDoc.Append("") For x As Int32 = 0 To gView.Columns.Count - 1 'Only write out columns that have column headers. If Not gView.Columns(x).HeaderText = String.Empty Then excelDoc.Append("") excelDoc.Append(gView.Columns(x).HeaderText.ToString) excelDoc.Append("") End If Next excelDoc.Append("") For r As Int32 = 0 To gView.Rows.Count - 1 rowCount += rowCount If rowCount = 64000 Then rowCount = 0 sheetCount += sheetCount excelDoc.Append("") excelDoc.Append(" ") excelDoc.Append("") excelDoc.Append("") End If excelDoc.Append("") For c As Int32 = 0 To gView.Rows(r).Cells.Count - 1 'Don't write out a column without a column header. If Not gView.Columns(c).HeaderText = String.Empty Then Dim XMLstring As String = gView.Rows(r).Cells(c).Text XMLstring = XMLstring.Trim() XMLstring = XMLstring.Replace("&", "&") XMLstring = XMLstring.Replace(">", ">") XMLstring = XMLstring.Replace("" + "") excelDoc.Append(XMLstring) excelDoc.Append("") End If Next excelDoc.Append("") Next excelDoc.Append("") excelDoc.Append(" ") excelDoc.Append(endExcelXML) Return excelDoc.ToString End Function Shared Sub PrepareGridViewForExport(ByVal gview As System.Web.UI.Control) ' Cleans up grid for exporting. Takes links and visual elements and turns them into text. Dim lb As New System.Web.UI.WebControls.LinkButton Dim l As New System.Web.UI.WebControls.Literal Dim name As String = String.Empty For i As Int32 = 0 To gview.Controls.Count - 1 If TypeOf gview.Controls(i) Is System.Web.UI.WebControls.LinkButton Then l.Text = CType(gview.Controls(i), System.Web.UI.WebControls.LinkButton).Text gview.Controls.Remove(gview.Controls(i)) gview.Controls.AddAt(i, l) ElseIf TypeOf gview.Controls(i) Is System.Web.UI.WebControls.DropDownList Then l.Text = CType(gview.Controls(i), System.Web.UI.WebControls.DropDownList).SelectedItem.Text gview.Controls.Remove(gview.Controls(i)) gview.Controls.AddAt(i, l) ElseIf TypeOf gview.Controls(i) Is System.Web.UI.WebControls.CheckBox Then l.Text = CType(gview.Controls(i), System.Web.UI.WebControls.CheckBox).Checked.ToString gview.Controls.Remove(gview.Controls(i)) gview.Controls.AddAt(i, l) End If If gview.Controls(i).HasControls() Then PrepareGridViewForExport(gview.Controls(i)) End If Next End Sub
回答
尝试一下,它比Brendans触摸简单,但不如"功能丰富":
Protected Sub btnExport_Click(ByVal sender As Object, ByVal e As System.EventArgs) 'Export to excel Response.Clear() Response.Buffer = True Response.ContentType = "application/vnd.ms-excel" Response.Charset = "" Me.EnableViewState = False Dim oStringWriter As System.IO.StringWriter = New System.IO.StringWriter Dim oHtmlTextWriter As System.Web.UI.HtmlTextWriter = New System.Web.UI.HtmlTextWriter(oStringWriter) Me.ClearControls(gvSearchTerms) gvSearchTerms.RenderControl(oHtmlTextWriter) Response.Write(oStringWriter.ToString) Response.End() End Sub Private Sub ClearControls(ByVal control As Control) Dim i As Integer = (control.Controls.Count - 1) Do While (i >= 0) ClearControls(control.Controls(i)) i = (i - 1) Loop If Not (TypeOf control Is TableCell) Then If (Not (control.GetType.GetProperty("SelectedItem")) Is Nothing) Then Dim literal As LiteralControl = New LiteralControl control.Parent.Controls.Add(literal) Try literal.Text = CType(control.GetType.GetProperty("SelectedItem").GetValue(control, Nothing), String) Catch ex As System.Exception End Try control.Parent.Controls.Remove(control) ElseIf (Not (control.GetType.GetProperty("Text")) Is Nothing) Then Dim literal As LiteralControl = New LiteralControl control.Parent.Controls.Add(literal) literal.Text = CType(control.GetType.GetProperty("Text").GetValue(control, Nothing), String) control.Parent.Controls.Remove(control) End If End If Return End Sub Public Overrides Sub VerifyRenderingInServerForm(ByVal control As Control) Return End Sub
回答
我们可以使用Crystal,因为它是VS内置的。用适当的列预定义一个水晶报表,然后我们可以使用任何用于数据网格或者网格视图的数据源。
Dim report_source As CrystalDecisions.Web.CrystalReportSource report_source.ReportDocument.SetDataSource(dt) 'DT IS A DATATABLE report_source.Report.FileName = "test.rpt" report_source.ReportDocument.Refresh() report_source.ReportDocument.ExportToDisk(CrystalDecisions.Shared.ExportFormatType.Excel, "c:\test.xls")
回答
我再次警告要进行两次for循环,以提取每个数据单元格的数据,并将其分别写到excel单元格中。而是使用2D对象数组,并遍历数据网格,将所有数据保存在那里。然后,我们将能够设置一个等于该2D对象数组的excel范围。
这将比逐单元写入excel快几个数量级。我一直在处理的报告过去仅花费两个小时就导出了,现在已减少到一分钟以内。
回答
我设置了gridview,然后使用html文本编写器对象将其吐到.xls文件中,如下所示:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 'get the select command of the gridview sqlGridview.SelectCommand = Session("strSql") gvCompaniesExport.DataBind() lblTemp.Text = Session("strSql") 'do the export doExport() 'close the window Dim closeScript As String = "<script language='javascript'> window.close() </scri" closeScript = closeScript & "pt>" 'split the ending script tag across a concatenate to keep it from causing problems 'this will write it to the asp.net page and fire it off, closing the window Page.RegisterStartupScript("closeScript", closeScript) End Sub Public Sub doExport() Response.AddHeader("content-disposition", "attachment;filename=IndianaCompanies.xls") Response.ContentType = "application/vnd.ms-excel" Response.Charset = "" Me.EnableViewState = False Dim objStrWriter As New System.IO.StringWriter Dim objHtmlTextWriter As New System.Web.UI.HtmlTextWriter(objStrWriter) 'Get the gridview HTML from the control gvCompaniesExport.RenderControl(objHtmlTextWriter) 'writes the dg info Response.Write(objStrWriter.ToString()) Response.End() End Sub
回答
我们可以使用该库进行更详细的格式化
http://www.carlosag.net/Tools/ExcelXmlWriter/
页面中有示例。
回答
我经常用这个:
public static class GridViewExtensions { public static void ExportToExcel(this GridView gridView, string fileName, IEnumerable<string> excludeColumnNames) { //Prepare Response HttpContext.Current.Response.Clear(); HttpContext.Current.Response.AddHeader("content-disposition", string.Format("attachment; filename={0}", fileName)); HttpContext.Current.Response.ContentType = "application/ms-excel"; using (StringWriter sw = new StringWriter()) { using (HtmlTextWriter htw = new HtmlTextWriter(sw)) { // Create a table to contain the grid Table table = new Table(); // include the gridline settings table.GridLines = gridView.GridLines; // add the header row to the table if (gridView.HeaderRow != null) { PrepareControlForExport(gridView.HeaderRow); table.Rows.Add(gridView.HeaderRow); } // add each of the data rows to the table foreach (GridViewRow row in gridView.Rows) { PrepareControlForExport(row); table.Rows.Add(row); } // add the footer row to the table if (gridView.FooterRow != null) { PrepareControlForExport(gridView.FooterRow); table.Rows.Add(gridView.FooterRow); } // Remove unwanted columns (header text listed in removeColumnList arraylist) foreach (DataControlField column in gridView.Columns) { if (excludeColumnNames != null && excludeColumnNames.Contains(column.HeaderText)) { column.Visible = false; } } // render the table into the htmlwriter table.RenderControl(htw); // render the htmlwriter into the response HttpContext.Current.Response.Write(sw.ToString()); HttpContext.Current.Response.End(); } } } /// <summary> /// Replace any of the contained controls with literals /// </summary> /// <param name="control"></param> private static void PrepareControlForExport(Control control) { for (int i = 0; i < control.Controls.Count; i++) { Control current = control.Controls[i]; if (current is LinkButton) { control.Controls.Remove(current); control.Controls.AddAt(i, new LiteralControl((current as LinkButton).Text)); } else if (current is ImageButton) { control.Controls.Remove(current); control.Controls.AddAt(i, new LiteralControl((current as ImageButton).AlternateText)); } else if (current is HyperLink) { control.Controls.Remove(current); control.Controls.AddAt(i, new LiteralControl((current as HyperLink).Text)); } else if (current is DropDownList) { control.Controls.Remove(current); control.Controls.AddAt(i, new LiteralControl((current as DropDownList).SelectedItem.Text)); } else if (current is CheckBox) { control.Controls.Remove(current); control.Controls.AddAt(i, new LiteralControl((current as CheckBox).Checked ? "True" : "False")); } if (current.HasControls()) { PrepareControlForExport(current); } } } }