【发布时间】:2010-10-15 09:03:43
【问题描述】:
我在 vb.net 中有一个从数据库中填充的 datagridview。我进行了研究,发现没有内置支持直接从 datagridview 打印。我不想用水晶报表,因为我不熟悉。
我打算将它导出到 excel 中,以便我能够从 datagridview 生成报告。
你能给我提供方法吗?
【问题讨论】:
标签: vb.net excel datagridview printing
我在 vb.net 中有一个从数据库中填充的 datagridview。我进行了研究,发现没有内置支持直接从 datagridview 打印。我不想用水晶报表,因为我不熟悉。
我打算将它导出到 excel 中,以便我能够从 datagridview 生成报告。
你能给我提供方法吗?
【问题讨论】:
标签: vb.net excel datagridview printing
以下代码创建 Excel 文件并将其保存在 D: 驱动器中 它使用 Microsoft Office 2007
首先将引用(Microsoft office 12.0 对象库)添加到您的项目
然后将下面给出的代码添加到导出按钮单击事件-
Private Sub Export_Button_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles VIEW_Button.Click
Dim xlApp As Microsoft.Office.Interop.Excel.Application
Dim xlWorkBook As Microsoft.Office.Interop.Excel.Workbook
Dim xlWorkSheet As Microsoft.Office.Interop.Excel.Worksheet
Dim misValue As Object = System.Reflection.Missing.Value
Dim i As Integer
Dim j As Integer
xlApp = New Microsoft.Office.Interop.Excel.ApplicationClass
xlWorkBook = xlApp.Workbooks.Add(misValue)
xlWorkSheet = xlWorkBook.Sheets("sheet1")
For i = 0 To DataGridView1.RowCount - 2
For j = 0 To DataGridView1.ColumnCount - 1
For k As Integer = 1 To DataGridView1.Columns.Count
xlWorkSheet.Cells(1, k) = DataGridView1.Columns(k - 1).HeaderText
xlWorkSheet.Cells(i + 2, j + 1) = DataGridView1(j, i).Value.ToString()
Next
Next
Next
xlWorkSheet.SaveAs("D:\vbexcel.xlsx")
xlWorkBook.Close()
xlApp.Quit()
releaseObject(xlApp)
releaseObject(xlWorkBook)
releaseObject(xlWorkSheet)
MsgBox("You can find the file D:\vbexcel.xlsx")
End Sub
Private Sub releaseObject(ByVal obj As Object)
Try
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
obj = Nothing
Catch ex As Exception
obj = Nothing
Finally
GC.Collect()
End Try
End Sub
【讨论】:
Excel方法
此方法与您将看到的许多方法不同。其他人使用循环来写入每个单元格并使用文本数据类型写入单元格。
此方法从DataTable 或DataGridView 创建一个对象数组,然后将该数组写入 Excel。这意味着我可以在没有循环的情况下写入 Excel 并保留数据类型。
我从我的库中提取了它,并且我认为我对其进行了足够的更改,以便仅使用此代码,但可能需要进行更多细微的调整。如果您遇到错误,请告诉我,我会为您更正。通常,我创建我的类的一个实例并调用这些方法。如果您想使用我的库,请使用此链接下载它,如果您需要帮助,请告诉我。
https://zomp.co/Files.aspx?ID=zExcel
将代码复制到您的解决方案后,您将像这样使用它。
在您的按钮代码中添加此项并将名称更改为您的控件。
WriteDataGrid("Sheet1", grid)
要在导出后打开文件,请使用此行
System.Diagnostics.Process.Start("The location and filename of your file")
在WriteArray 方法中,您需要将保存工作簿的行更改到您要保存的位置。将其添加为参数可能是有意义的。
wb.SaveAs("C:\MyWorkbook.xlsx")
Public Function WriteArray(Sheet As String, ByRef ObjectArray As Object(,)) As String
Try
Dim xl As Excel.Application = New Excel.Application
Dim wb As Excel.Workbook = xl.Workbooks.Add()
Dim ws As Excel.Worksheet = wb.Worksheets.Add()
ws.Name = Sheet
Dim range As Excel.Range = ws.Range("A1").Resize(ObjectArray.GetLength(0), ObjectArray.GetLength(1))
range.Value = ObjectArray
range = ws.Range("A1").Resize(1, ObjectArray.GetLength(1) - 1)
range.Interior.Color = RGB(0, 70, 132) 'Con-way Blue
range.Font.Color = RGB(Drawing.Color.White.R, Drawing.Color.White.G, Drawing.Color.White.B)
range.Font.Bold = True
range.WrapText = True
range.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter
range.VerticalAlignment = Excel.XlVAlign.xlVAlignCenter
range.Application.ActiveWindow.SplitColumn = 0
range.Application.ActiveWindow.SplitRow = 1
range.Application.ActiveWindow.FreezePanes = True
wb.SaveAs("C:\MyWorkbook.xlsx")
wb.CLose()
xl.Quit()
xl = Nothing
wb = Nothing
ws = Nothing
range = Nothing
ReleaseComObject(xl)
ReleaseComObject(wb)
ReleaseComObject(ws)
ReleaseComObject(range)
Return ""
Catch ex As Exception
Return "WriteArray()" & Environment.NewLine & Environment.NewLine & ex.Message
End Try
End Function
Public Function WriteDataGrid(SheetName As String, ByRef dt As DataGridView) As String
Try
Dim l(dt.Rows.Count + 1, dt.Columns.Count) As Object
For c As Integer = 0 To dt.Columns.Count - 1
l(0, c) = dt.Columns(c).HeaderText
Next
For r As Integer = 1 To dt.Rows.Count
For c As Integer = 0 To dt.Columns.Count - 1
l(r, c) = dt.Rows(r - 1).Cells(c)
Next
Next
Dim errors As String = WriteArray(SheetName, l)
If errors <> "" Then
Return errors
End If
Return ""
Catch ex As Exception
Return "WriteDataGrid()" & Environment.NewLine & Environment.NewLine & ex.Message
End Try
End Function
Public Function WriteDataTable(SheetName As String, ByRef dt As DataTable) As String
Try
Dim l(dt.Rows.Count + 1, dt.Columns.Count) As Object
For c As Integer = 0 To dt.Columns.Count - 1
l(0, c) = dt.Columns(c).ColumnName
Next
For r As Integer = 1 To dt.Rows.Count
For c As Integer = 0 To dt.Columns.Count - 1
l(r, c) = dt.Rows(r - 1).Item(c)
Next
Next
Dim errors As String = WriteArray(SheetName, l)
If errors <> "" Then
Return errors
End If
Return ""
Catch ex As Exception
Return "WriteDataTable()" & Environment.NewLine & Environment.NewLine & ex.Message
End Try
End Function
我实际上并没有在我的数据库程序中使用这种方法,因为当您有很多行/列时,它是一种缓慢的方法。我改为从 DataGridView 创建一个 CSV。仅当您需要格式化数据和单元格时,使用 Excel 自动化写入 Excel 才有用,否则您应该使用 CSV。您可以使用图像后的代码进行 CSV 导出。
CSV 方法
Private Sub DataGridToCSV(ByRef dt As DataGridView, Qualifier As String)
Dim TempDirectory As String = "A temp Directory"
System.IO.Directory.CreateDirectory(TempDirectory)
Dim oWrite As System.IO.StreamWriter
Dim file As String = System.IO.Path.GetRandomFileName & ".csv"
oWrite = IO.File.CreateText(TempDirectory & "\" & file)
Dim CSV As StringBuilder = New StringBuilder()
Dim i As Integer = 1
Dim CSVHeader As StringBuilder = New StringBuilder()
For Each c As DataGridViewColumn In dt.Columns
If i = 1 Then
CSVHeader.Append(Qualifier & c.HeaderText.ToString() & Qualifier)
Else
CSVHeader.Append("," & Qualifier & c.HeaderText.ToString() & Qualifier)
End If
i += 1
Next
'CSV.AppendLine(CSVHeader.ToString())
oWrite.WriteLine(CSVHeader.ToString())
oWrite.Flush()
For r As Integer = 0 To dt.Rows.Count - 1
Dim CSVLine As StringBuilder = New StringBuilder()
Dim s As String = ""
For c As Integer = 0 To dt.Columns.Count - 1
If c = 0 Then
'CSVLine.Append(Qualifier & gridResults.Rows(r).Cells(c).Value.ToString() & Qualifier)
s = s & Qualifier & gridResults.Rows(r).Cells(c).Value.ToString() & Qualifier
Else
'CSVLine.Append("," & Qualifier & gridResults.Rows(r).Cells(c).Value.ToString() & Qualifier)
s = s & "," & Qualifier & gridResults.Rows(r).Cells(c).Value.ToString() & Qualifier
End If
Next
oWrite.WriteLine(s)
oWrite.Flush()
'CSV.AppendLine(CSVLine.ToString())
'CSVLine.Clear()
Next
'oWrite.Write(CSV.ToString())
oWrite.Close()
oWrite = Nothing
System.Diagnostics.Process.Start(TempDirectory & "\" & file)
GC.Collect()
End Sub
【讨论】:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
DATAGRIDVIEW_TO_EXCEL((DataGridView1)) ' PARAMETER: YOUR DATAGRIDVIEW
End Sub
Private Sub DATAGRIDVIEW_TO_EXCEL(ByVal DGV As DataGridView)
Try
Dim DTB = New DataTable, RWS As Integer, CLS As Integer
For CLS = 0 To DGV.ColumnCount - 1 ' COLUMNS OF DTB
DTB.Columns.Add(DGV.Columns(CLS).Name.ToString)
Next
Dim DRW As DataRow
For RWS = 0 To DGV.Rows.Count - 1 ' FILL DTB WITH DATAGRIDVIEW
DRW = DTB.NewRow
For CLS = 0 To DGV.ColumnCount - 1
Try
DRW(DTB.Columns(CLS).ColumnName.ToString) = DGV.Rows(RWS).Cells(CLS).Value.ToString
Catch ex As Exception
End Try
Next
DTB.Rows.Add(DRW)
Next
DTB.AcceptChanges()
Dim DST As New DataSet
DST.Tables.Add(DTB)
Dim FLE As String = "" ' PATH AND FILE NAME WHERE THE XML WIL BE CREATED (EXEMPLE: C:\REPS\XML.xml)
DTB.WriteXml(FLE)
Dim EXL As String = "" ' PATH OF/ EXCEL.EXE IN YOUR MICROSOFT OFFICE
Shell(Chr(34) & EXL & Chr(34) & " " & Chr(34) & FLE & Chr(34), vbNormalFocus) ' OPEN XML WITH EXCEL
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
【讨论】:
关于您需要“直接从 datagridview 打印”,请查看 CodeProject 上的这篇文章:
有许多类似的文章,但我很幸运地看到了我链接的那一篇。
【讨论】:
下面的代码对我来说很好:)
Protected Sub ExportToExcel(sender As Object, e As EventArgs) Handles ExportExcel.Click
Try
Response.Clear()
Response.Buffer = True
Response.AddHeader("content-disposition", "attachment;filename=ExportEthias.xls")
Response.Charset = ""
Response.ContentType = "application/vnd.ms-excel"
Using sw As New StringWriter()
Dim hw As New HtmlTextWriter(sw)
GvActifs.RenderControl(hw)
'Le format de base est le texte pour éviter les problèmes d'arrondis des nombres
Dim style As String = "<style> .textmode { } </style>"
Response.Write(Style)
Response.Output.Write(sw.ToString())
Response.Flush()
Response.End()
End Using
Catch ex As Exception
lblMessage.Text = "Erreur export Excel : " & ex.Message
End Try
End Sub
Public Overrides Sub VerifyRenderingInServerForm(control As Control)
' Verifies that the control is rendered
End Sub
希望对您有所帮助。
【讨论】:
将 rowNo1 变暗 Dim numrow As Short Dim colNo1 As Short 将 colNo2 暗淡为短
rowNo1 = 1
colNo1 = 1
colNo2 = 1
numrow = 1
ObjEXCEL = CType(CreateObject("Excel.Application"), Microsoft.Office.Interop.Excel.Application)
objEXCELBook = CType(ObjEXCEL.Workbooks.Add, Microsoft.Office.Interop.Excel.Workbook)
objEXCELSheet = CType(objEXCELBook.Worksheets(1), Microsoft.Office.Interop.Excel.Worksheet)
ObjEXCEL.Visible = True
For numCounter = 0 To grdName.Columns.Count - 1
' MsgBox(grdName.Columns(numCounter).HeaderText())
If grdName.Columns(numCounter).Width > 0 Then
ObjEXCEL.Cells(1, numCounter + 1) = grdName.Columns(numCounter).HeaderText()
End If
' ObjEXCEL.Cells(1, numCounter + 1) = grdName.Columns.GetFirstColumn(DataGridViewElementStates.Displayed)
Next numCounter
ObjEXCEL.Range("A:A").ColumnWidth = 10
ObjEXCEL.Range("B:B").ColumnWidth = 25
ObjEXCEL.Range("C:C").ColumnWidth = 20
ObjEXCEL.Range("D:D").ColumnWidth = 20
ObjEXCEL.Range("E:E").ColumnWidth = 20
ObjEXCEL.Range("F:F").ColumnWidth = 25
For rowNo1 = 0 To grdName.RowCount - 1
For colNo1 = 0 To grdName.ColumnCount - 1
If grdName.Columns(colNo1).Width > 0 Then
If Trim(grdName.Item(colNo1, rowNo1).Value) <> "" Then
'If IsDate(grdName.Item(colNo1, rowNo1).Value) = True Then
' ObjEXCEL.Cells(numrow + 1, colNo2) = Format(CDate(grdName.Item(colNo1, rowNo1).Value), "dd/MMM/yyyy")
'Else
ObjEXCEL.Cells(numrow + 1, colNo2) = grdName.Item(colNo1, rowNo1).Value
'End If
End If
If colNo2 >= grdName.ColumnCount Then
colNo2 = 1
Else
colNo2 = colNo2 + 1
End If
End If
Next colNo1
numrow = numrow + 1
Next rowNo1
【讨论】:
在设计模式下:将DataGridView1 ClipboardCopyMode 属性设置为EnableAlwaysIncludeHeaderText
还是关于程序代码
DataGridView1.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText
在运行时选择所有单元格内容 (Ctrl+A) 并复制 (Ctrl+C) 并粘贴到 Excel 程序。 让 Excel 完成剩下的工作
很抱歉,我一直在寻找直接从datagridvew打印数据的方法(从vb.net VB2012创建报告),没有找到满意的结果。 上面的代码只是我的,想知道我的应用程序用户是否可以依赖上面的简单步骤,这会很好,我可以继续下一步我的程序进度。
【讨论】:
从 Datagridview 生成可打印报表的一种简单方法是将 datagridview 放在 Panel 对象上。可以绘制面板的位图。
这就是我的做法。
'用面板的尺寸创建位图 Dim bmp As New Bitmap(Panel1.Width, Panel1.Height)
'将Panel绘制到位图“bmp” Panel1.DrawToBitmap(bmp, Panel1.ClientRectangle)
我通过“将我的 datagridview 项目分成页面来创建多页 tiff。 这就是我检测新页面开始的方式:
'我一次将一行添加到我的数据网格中,然后检查滚动条是否处于活动状态。 '如果滚动条处于活动状态,我将行保存到变量中,然后将其从 'datagridview 并将我的计数器整数回滚一个(因此下一次运行将包括这个 '行。
Private Function VScrollBarVisible() As Boolean
Dim ctrl As New Control
For Each ctrl In DataGridView_Results.Controls
If ctrl.GetType() Is GetType(VScrollBar) Then
If ctrl.Visible = True Then
Return True
Else
Return False
End If
End If
Next
Return Nothing
End Function
希望对你有帮助
【讨论】:
另一种更简单、更灵活的方法,在将数据加载到 Datagrid 之后
Private Sub Button_Export_Click(sender As Object, e As EventArgs) Handles Button_Export.Click
Dim file As System.IO.StreamWriter
file = My.Computer.FileSystem.OpenTextFileWriter("c:\1\Myfile.csv", True)
If DataGridView1.Rows.Count = 0 Then GoTo loopend
' collect the header's names
Dim Headerline As String
For k = 0 To DataGridView1.Columns.Count - 1
If k = DataGridView1.Columns.Count - 1 Then ' last column dont put , separate
Headerline = Headerline & DataGridView1.Columns(k).HeaderText
Else
Headerline = Headerline & DataGridView1.Columns(k).HeaderText & ","
End If
Next
file.WriteLine(Headerline) ' this will write header names at the first line
' collect the data
For i = 0 To DataGridView1.Rows.Count - 1
Dim DataRow As String
For k = 0 To DataGridView1.Columns.Count - 1
If k = DataGridView1.Columns.Count - 1 Then
DataRow = DataRow & DataGridView1.Rows(i).Cells(k).Value ' last column dont put , separate
End If
DataRow = DataRow & DataGridView1.Rows(i).Cells(k).Value & ","
Next
file.WriteLine(DataRow)
DataRow = ""
Next
loopend:
file.Close()
End Sub
【讨论】: