将过滤后的 Datagridview 导出为 excel 或 pdf (SQL Server)
Posted
技术标签:
【中文标题】将过滤后的 Datagridview 导出为 excel 或 pdf (SQL Server)【英文标题】:Exporting Filtered Datagridview to excel or pdf (SQL Server) 【发布时间】:2021-12-11 01:58:17 【问题描述】:我希望我的应用程序导出 datagridview 上的任何内容,包括过滤器。这是我的应用程序的布局:
组合框包含所有列的名称。搜索栏搜索该列内的数据。代码是这样的:
Imports System.Data.SqlClient
Imports System.IO
Imports ClosedXML.Excel
Imports System.Data.DataSetExtensions.dll
Public Class export
Dim con As New SqlConnection("Data Source=ICECANDY;Initial Catalog=RestaurantDatabase;integrated security=true")
Sub DGVSETPROPERTY()
DataGridView1.Columns(0).Width = 40
DataGridView1.Columns(0).HeaderText = "TaskID"
DataGridView1.Columns(0).Width = 40
DataGridView1.Columns(0).HeaderText = "Name"
DataGridView1.Columns(0).Width = 40
DataGridView1.Columns(0).HeaderText = "TaskCategory"
DataGridView1.Columns(0).Width = 40
DataGridView1.Columns(0).HeaderText = "TaskAssigned"
DataGridView1.Columns(0).Width = 40
DataGridView1.Columns(0).HeaderText = "TimeIssued"
DataGridView1.Columns(0).Width = 40
DataGridView1.Columns(0).HeaderText = "TargetTime"
DataGridView1.Columns(0).Width = 40
DataGridView1.Columns(0).HeaderText = "StartTime"
DataGridView1.Columns(0).Width = 40
DataGridView1.Columns(0).HeaderText = "FinishTime"
DataGridView1.Columns(0).Width = 40
DataGridView1.Columns(0).HeaderText = "Status"
End Sub
Sub view()
Try
Dim singh As New SqlDataAdapter("SELECT TOP (1000) [TaskID]
,[Name]
,[TaskCategory]
,[TaskAssigned]
,[TimeIssued]
,[TargetTime]
,[StartTime]
,[FinishTime]
,[Status]
FROM [RestaurantDatabase].[dbo].[Tasks]", con)
Dim bumrah As New DataSet()
singh.Fill(bumrah)
DataGridView1.DataSource = bumrah.Tables(0)
DGVSETPROPERTY()
Catch ex As Exception
MessageBox.Show(ex.ToString())
End Try
End Sub
Private Sub export_Load(sender As Object, e As EventArgs) Handles MyBase.Load
view()
End Sub
Private Sub export_Resize(sender As Object, e As EventArgs) Handles Me.Resize
Panel1.Left = (Me.Width - Panel1.Width) / 2
End Sub
Private Sub txtsearch_TextChanged(sender As Object, e As EventArgs) Handles txtsearch.TextChanged
Try
If ComboBox.Text = "TaskID" Then
Dim singh As New SqlDataAdapter("SELECT TOP (1000) [TaskID]
,[Name]
,[TaskCategory]
,[TaskAssigned]
,[TimeIssued]
,[TargetTime]
,[StartTime]
,[FinishTime]
,[Status]
FROM [RestaurantDatabase].[dbo].[Tasks] where TaskID Like '" + txtsearch.Text + "%'", con)
Dim bumrah As New DataSet()
singh.Fill(bumrah)
DataGridView1.DataSource = bumrah.Tables(0)
ElseIf ComboBox.Text = "Name" Then
Dim singh As New SqlDataAdapter("SELECT TOP (1000) [TaskID]
,[Name]
,[TaskCategory]
,[TaskAssigned]
,[TimeIssued]
,[TargetTime]
,[StartTime]
,[FinishTime]
,[Status]
FROM [RestaurantDatabase].[dbo].[Tasks] where Name Like '" + txtsearch.Text + "%'", con)
Dim bumrah As New DataSet()
singh.Fill(bumrah)
DataGridView1.DataSource = bumrah.Tables(0)
ElseIf ComboBox.Text = "TaskCategory" Then
Dim singh As New SqlDataAdapter("SELECT TOP (1000) [TaskID]
,[Name]
,[TaskCategory]
,[TaskAssigned]
,[TimeIssued]
,[TargetTime]
,[StartTime]
,[FinishTime]
,[Status]
FROM [RestaurantDatabase].[dbo].[Tasks] where TaskCategory Like '" + txtsearch.Text + "%'", con)
Dim bumrah As New DataSet()
singh.Fill(bumrah)
DataGridView1.DataSource = bumrah.Tables(0)
ElseIf ComboBox.Text = "TimeIssued" Then
Dim singh As New SqlDataAdapter("SELECT TOP (1000) [TaskID]
,[Name]
,[TaskCategory]
,[TaskAssigned]
,[TimeIssued]
,[TargetTime]
,[StartTime]
,[FinishTime]
,[Status]
FROM [RestaurantDatabase].[dbo].[Tasks] where TimeIssued Like '" + txtsearch.Text + "%'", con)
Dim bumrah As New DataSet()
singh.Fill(bumrah)
DataGridView1.DataSource = bumrah.Tables(0)
ElseIf ComboBox.Text = "TargetTime" Then
Dim singh As New SqlDataAdapter("SELECT TOP (1000) [TaskID]
,[Name]
,[TaskCategory]
,[TaskAssigned]
,[TimeIssued]
,[TargetTime]
,[StartTime]
,[FinishTime]
,[Status]
FROM [RestaurantDatabase].[dbo].[Tasks] where TargetTime Like '" + txtsearch.Text + "%'", con)
Dim bumrah As New DataSet()
singh.Fill(bumrah)
DataGridView1.DataSource = bumrah.Tables(0)
ElseIf ComboBox.Text = "StartTime" Then
Dim singh As New SqlDataAdapter("SELECT TOP (1000) [TaskID]
,[Name]
,[TaskCategory]
,[TaskAssigned]
,[TimeIssued]
,[TargetTime]
,[StartTime]
,[FinishTime]
,[Status]
FROM [RestaurantDatabase].[dbo].[Tasks] where StartTime Like '" + txtsearch.Text + "%'", con)
Dim bumrah As New DataSet()
singh.Fill(bumrah)
DataGridView1.DataSource = bumrah.Tables(0)
ElseIf ComboBox.Text = "FinishTime" Then
Dim singh As New SqlDataAdapter("SELECT TOP (1000) [TaskID]
,[Name]
,[TaskCategory]
,[TaskAssigned]
,[TimeIssued]
,[TargetTime]
,[StartTime]
,[FinishTime]
,[Status]
FROM [RestaurantDatabase].[dbo].[Tasks] where FinishTime Like '" + txtsearch.Text + "%'", con)
Dim bumrah As New DataSet()
singh.Fill(bumrah)
DataGridView1.DataSource = bumrah.Tables(0)
ElseIf ComboBox.Text = "Status" Then
Dim singh As New SqlDataAdapter("SELECT TOP (1000) [TaskID]
,[Name]
,[TaskCategory]
,[TaskAssigned]
,[TimeIssued]
,[TargetTime]
,[StartTime]
,[FinishTime]
,[Status]
FROM [RestaurantDatabase].[dbo].[Tasks] where Status Like '" + txtsearch.Text + "%'", con)
Dim bumrah As New DataSet()
singh.Fill(bumrah)
DataGridView1.DataSource = bumrah.Tables(0)
End If
Catch ex As Exception
MessageBox.Show(ex.ToString())
End Try
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Try
Dim singh As New SqlDataAdapter("SELECT TOP (1000) [TaskID]
,[Name]
,[TaskCategory]
,[TaskAssigned]
,[TimeIssued]
,[TargetTime]
,[StartTime]
,[FinishTime]
,[Status]
FROM [RestaurantDatabase].[dbo].[Tasks]", con)
Dim bumrah As New DataSet()
singh.Fill(bumrah)
DataGridView1.DataSource = bumrah.Tables(0)
DGVSETPROPERTY()
Catch ex As Exception
MessageBox.Show(ex.ToString())
End Try
End Sub
End Class
我想导出过滤后的数据。 pdf或excel都可以。
【问题讨论】:
连接应该在使用它们的方法中的使用块中声明。他们必须调用Dispose
方法,然后 End Using
执行此操作并关闭连接。
不要连接 SQL 字符串。使用参数。
如果您只使用DataAdapter
中的单个表,请不要使用DataSet
,使用DataTable
。
为了弄清楚这一点,您已经成功地从数据库中提取了您想要的数据(甚至在玛丽提出非常有效的建议之前)?现在您希望将其导出?如果是这样的话,这一切都很好,很好地向我们展示了有效的代码,但是尝试导出无效的代码呢?已经有大量示例和现有工具可以做到这一点
【参考方案1】:
编程中有一个原则叫做 DRY。它代表不要重复自己。我想你可以看到你违反了这个原则。当你构建 Sql 字符串时,就像我在这里所做的那样,小心空格。你需要在单词之间留一个空格。我试图把它放在字符串的末尾。 Debug.Print 将显示字符串是否正确输出。
当您有一系列针对相同值的 If 语句时,Select Case 更易于阅读和编写。
不必将列标题添加到 DataGridView。 DataTable 到网格的绑定将处理这个问题。我相信这些列会自动调整大小以适应数据。
ADO.net 中的几个数据库对象提供了一个 Dispose 方法,用于释放非托管资源。如果有一个 Dispose 方法,它应该被调用。 Using...End Using 块即使出现错误也会为我们执行此操作(它也会关闭连接)。这些对象需要在 Using 块中使用它们的方法中声明。
不要乱用 DataGridView。您只需要 DataTable 即可与 Excel 进行交互。
关闭 Excel 的 Wrapper 可能看起来很奇怪,但 Excel 在 b_tch 中可以摆脱。我相信这里的安排是可行的。
Private Sub txtsearch_TextChanged(sender As Object, e As EventArgs) Handles txtsearch.TextChanged
Dim Field = ComboBox1.Text
Dim strSQL = "SELECT TOP (1000)
[TaskID],
[Name],
[TaskCategory],
[TaskAssigned],
[TimeIssued],
[TargetTime],
[StartTime],
[FinishTime],
[Status]
FROM [RestaurantDatabase].[dbo].[Tasks]
WHERE "
Select Case Field
Case "TaskID"
strSQL &= "TaskID "
Case "Name"
strSQL &= "Name "
Case "TaskCategory"
strSQL &= "TaskCategory "
Case "TimeIssued"
strSQL &= "TimeIssued "
Case "TargetTime"
strSQL &= "TargetTime "
Case "StartTime"
strSQL = "StartTime "
Case "FinishTime"
strSQL &= "FinishTime "
Case "Status"
strSQL &= "Status "
End Select
strSQL &= "Like @Search;"
Debug.Print(strSQL)
Dim dt As New DataTable
Try
Using cn As New SqlConnection(OPConStr),
cmd As New SqlCommand(strSQL, cn)
cmd.Parameters.Add("@Search", SqlDbType.VarChar).Value = txtsearch.Text & "%"
cn.Open()
Using reader = cmd.ExecuteReader
dt.Load(reader)
End Using
End Using
Catch ex As Exception
MessageBox.Show(ex.ToString())
End Try
DataGridView1.DataSource = dt
WrapperToGetRidOfExcel(dt)
End Sub
Private Sub WrapperToGetRidOfExcel(dt As DataTable)
FillExcelFromDataTable(dt)
GC.Collect()
GC.WaitForPendingFinalizers()
GC.Collect()
GC.WaitForPendingFinalizers()
End Sub
Private Sub FillExcelFromDataTable(dt As DataTable)
Dim oExcel As New Excel.Application
Dim oBook = oExcel.Workbooks.Add
Dim oSheet = DirectCast(oBook.Worksheets.Add, Excel.Worksheet)
Dim ColumnIndex = 1 'in the Excel worksheet
For Each col As DataColumn In dt.Columns 'This loop adds the header row
oSheet.Cells(1, ColumnIndex) = col.ColumnName
ColumnIndex += 1
Next
ColumnIndex = 1 'The columns and rows in the spreadsheet
Dim RowIndex = 2 'The columns and rows in the spreadsheet
For rowI = 0 To dt.Rows.Count - 1
For Each col As DataColumn In dt.Columns
oSheet.Cells(RowIndex, ColumnIndex) = dt(rowI)(col)
ColumnIndex += 1
Next
ColumnIndex = 1 'Reset back to the first column
RowIndex += 1
Next
oBook.Save()
oBook.SaveAs(Filename:="ExcelDat.xlsx")
oBook.Close()
oExcel.Quit()
End Sub
【讨论】:
感谢您的回答。我回家后会试试这个。很抱歉在编程方面缺乏能力。我只是在youtube上观看了视频以进行测试。我真的很感激帮助!我希望你有一个美好的一天。 另外一个问题,如何在您的代码中启动导出到 excel 功能?我没有看到激活它的按钮或其他东西。 txtsearch_TextChanged 的最后一行调用了包装器。包装器调用 Excel 的东西。 如何才能使导出仅在我按下按钮时才有效?我只是将包装器移到按钮上吗?我尝试了代码,但每次我在 txtsearch 文本框中输入内容时它都会导出。 @Andre'Bella 那是因为它开始于一个 TextChanged 事件,该事件在您每次键入字符时触发。使用按钮的好主意。将 TextChanged 中的所有代码移出到 button.Click.以上是关于将过滤后的 Datagridview 导出为 excel 或 pdf (SQL Server)的主要内容,如果未能解决你的问题,请参考以下文章
在 vb net 中显示从 1 个平板电脑到 2 个过滤后的 datagridview 的数据