如何将数据保存到一个 excel 文件中的 datagridview
How to save to datagridview data in one excel file
我正在使用 microsoft.excel.introp.dll 将 datagridview 数据保存到 excel 文件,我的问题是如何在一个文件中保存两个 datagridview 数据(sheet1 和 sheet2)
我正在使用此代码将第一个数据网格视图保存为 excel 文件:
Private Sub copyAlltoClipboard()
DataGridView1.SelectAll()
Dim dataObj As DataObject = DataGridView1.GetClipboardContent()
If dataObj IsNot Nothing Then Clipboard.SetDataObject(dataObj)
End Sub
Private Sub releaseObject(ByVal obj As Object)
Try
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
obj = Nothing
Catch ex As Exception
obj = Nothing
MessageBox.Show("Exception Occurred while releasing object " & ex.ToString())
Finally
GC.Collect()
End Try
End Sub
Dim sfd As SaveFileDialog = New SaveFileDialog()
sfd.Filter = "Microsoft Excel 97-2003 Workbook (*.xls)|*.xls"
sfd.FileName = NomTextBox.Text & "_" & PrenomTextBox.Text
If sfd.ShowDialog() = DialogResult.OK Then
copyAlltoClipboard()
Dim xlexcel As Excel.Application
Dim xlWorkBook As Excel.Workbook
Dim xlWorkSheet As Excel.Worksheet
Dim misValue As Object = System.Reflection.Missing.Value
xlexcel = New Excel.Application()
xlexcel.Visible = False
xlWorkBook = xlexcel.Workbooks.Add(misValue)
xlWorkSheet = CType(xlWorkBook.Worksheets.Item(1), Excel.Worksheet)
Dim CR As Excel.Range = CType(xlWorkSheet.Cells(1, 1), Excel.Range)
CR.[Select]()
xlWorkSheet.PasteSpecial(CR, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, True)
xlWorkBook.SaveAs(sfd.FileName, Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue)
xlexcel.DisplayAlerts = True
xlWorkBook.Close(True, misValue, misValue)
xlexcel.Quit()
releaseObject(xlWorkSheet)
releaseObject(xlWorkBook)
releaseObject(xlexcel)
Clipboard.Clear()
这不是我的代码,我从别人那里拿来并修改过的。
首先,您应该知道不建议使用 Interop
。还有其他 third-party 库在许多方面工作得更好并且有一些优势。也就是说,使用互操作需要目标计算机具有与代码使用的相同的 Excel 库。但是,我知道这可能是必需的或唯一的选择。如果是这种情况,那么下面的代码可能会有所帮助。
当前代码存在的一个问题是无法控制“工作表名称”应该是什么。恕我直言,最好给工作表一个“特定”名称,以便代码稍后可以用新数据覆盖文件。通过简单地添加新工作表,您最终可能会得到一堆具有相同数据的工作表。
因此,我创建了一个方法 GetWorksheet
,它接受一个 Workbook
和 String
name.
这个方法将 return 一个 Worksheet
要么“匹配”给定的名称,要么如果在给定的工作簿中找不到工作表名称,那么它将 return 一个具有给定名称的新工作表。这个方法可能看起来像……
Private Function GetWorksheet(wb As Excel.Workbook, name As String) As Excel.Worksheet
For Each ws In wb.Sheets
If ws.Name = name Then
Return ws
End If
Next
Dim newWS = wb.Worksheets.Add()
newWS.Name = name
Return newWS
End Function
上面的代码遍历给定工作簿中的所有工作表。如果找到与给定名称匹配的工作表名称,则该工作表将被 returned。如果未找到工作表名称,则会 returned 一个具有给定名称的新工作表。这将允许您将工作表命名为比“Sheet1”、“Sheet2”等更直观的名称。我们可以使用此方法获取现有工作表或为要添加到工作簿的每个网格创建新工作表。
接下来,第二个名为 AddSheetToWorkbook
的辅助方法需要一个工作簿、一个 DataGridView
和一个工作表名称...可能会使事情变得更容易。在此方法中,代码将 select 给定网格中的所有单元格。使用上述方法从给定的 (OPEN) 工作簿中获取具有给定工作表名称的工作表。然后将复制的单元格粘贴到工作表中。它可能看起来像……
Private Sub AddSheetToWorkbook(xlWorkBook As Excel.Workbook, dgv As DataGridView, wkSheetName As String)
dgv.SelectAll()
Dim dataObj As DataObject = dgv.GetClipboardContent()
If dataObj IsNot Nothing Then Clipboard.SetDataObject(dataObj)
Dim xlWorkSheet = GetWorksheet(xlWorkBook, wkSheetName)
Dim CR As Excel.Range = CType(xlWorkSheet.Cells(1, 1), Excel.Range)
CR.[Select]()
xlWorkSheet.PasteSpecial(CR, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, True)
End Sub
我们可以使用此方法将每个 DataGridView
添加到工作簿中的不同工作表。
最后,将所有这些放在一起可能如下所示。我使用了一些不同的方法,使用 Try/Catch/Finally
来确保 Excel COM objects 被正确处理,但是,在我的测试中,当前代码也有效。
该代码使用与当前代码相同的方法。使用 SaveFileDialog.
获取工作簿的文件名 创建一个新的 Excel 应用程序,添加工作簿,然后将两个网格添加到工作簿。每个网格都将位于一个单独的工作表上,并带有提供的工作表名称。文件已保存,Finally
COM
objects 已关闭并释放。
不清楚在当前发布的代码中“在哪里”调用了这段代码。在此示例中,代码是 运行 通过按表单上的按钮。
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim sfd As SaveFileDialog = New SaveFileDialog With {
.Filter = "Microsoft Excel 97-2003 Workbook (*.xls)|*.xls",
.FileName = NomTextBox.Text & "_" & PrenomTextBox.Text
}
If sfd.ShowDialog() = DialogResult.OK Then
Dim xlexcel As Excel.Application = Nothing
Dim xlWorkBook As Excel.Workbook = Nothing
Dim misValue As Object = Reflection.Missing.Value
Try
xlexcel = New Excel.Application()
xlWorkBook = xlexcel.Workbooks.Add()
AddSheetToWorkbook(xlWorkBook, DataGridView1, "Grid1")
AddSheetToWorkbook(xlWorkBook, DataGridView2, "Grid2")
xlWorkBook.SaveAs(sfd.FileName, Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue)
Catch ex As Exception
MessageBox.Show("Error: " + ex.Message)
Finally
If (xlWorkBook IsNot Nothing) Then
xlWorkBook.Close()
Runtime.InteropServices.Marshal.ReleaseComObject(xlWorkBook)
End If
If (xlexcel IsNot Nothing) Then
xlexcel.Quit()
Runtime.InteropServices.Marshal.ReleaseComObject(xlexcel)
End If
MessageBox.Show("Export Complete")
End Try
End If
End Sub
最后,我猜您不需要 Excel 文件中的 headers 列,因为 OS select all 和复制命令不会抓取网格列 header 文本。
我希望这是有道理的。
我正在使用 microsoft.excel.introp.dll 将 datagridview 数据保存到 excel 文件,我的问题是如何在一个文件中保存两个 datagridview 数据(sheet1 和 sheet2)
我正在使用此代码将第一个数据网格视图保存为 excel 文件:
Private Sub copyAlltoClipboard()
DataGridView1.SelectAll()
Dim dataObj As DataObject = DataGridView1.GetClipboardContent()
If dataObj IsNot Nothing Then Clipboard.SetDataObject(dataObj)
End Sub
Private Sub releaseObject(ByVal obj As Object)
Try
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
obj = Nothing
Catch ex As Exception
obj = Nothing
MessageBox.Show("Exception Occurred while releasing object " & ex.ToString())
Finally
GC.Collect()
End Try
End Sub
Dim sfd As SaveFileDialog = New SaveFileDialog()
sfd.Filter = "Microsoft Excel 97-2003 Workbook (*.xls)|*.xls"
sfd.FileName = NomTextBox.Text & "_" & PrenomTextBox.Text
If sfd.ShowDialog() = DialogResult.OK Then
copyAlltoClipboard()
Dim xlexcel As Excel.Application
Dim xlWorkBook As Excel.Workbook
Dim xlWorkSheet As Excel.Worksheet
Dim misValue As Object = System.Reflection.Missing.Value
xlexcel = New Excel.Application()
xlexcel.Visible = False
xlWorkBook = xlexcel.Workbooks.Add(misValue)
xlWorkSheet = CType(xlWorkBook.Worksheets.Item(1), Excel.Worksheet)
Dim CR As Excel.Range = CType(xlWorkSheet.Cells(1, 1), Excel.Range)
CR.[Select]()
xlWorkSheet.PasteSpecial(CR, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, True)
xlWorkBook.SaveAs(sfd.FileName, Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue)
xlexcel.DisplayAlerts = True
xlWorkBook.Close(True, misValue, misValue)
xlexcel.Quit()
releaseObject(xlWorkSheet)
releaseObject(xlWorkBook)
releaseObject(xlexcel)
Clipboard.Clear()
这不是我的代码,我从别人那里拿来并修改过的。
首先,您应该知道不建议使用 Interop
。还有其他 third-party 库在许多方面工作得更好并且有一些优势。也就是说,使用互操作需要目标计算机具有与代码使用的相同的 Excel 库。但是,我知道这可能是必需的或唯一的选择。如果是这种情况,那么下面的代码可能会有所帮助。
当前代码存在的一个问题是无法控制“工作表名称”应该是什么。恕我直言,最好给工作表一个“特定”名称,以便代码稍后可以用新数据覆盖文件。通过简单地添加新工作表,您最终可能会得到一堆具有相同数据的工作表。
因此,我创建了一个方法 GetWorksheet
,它接受一个 Workbook
和 String
name.
这个方法将 return 一个 Worksheet
要么“匹配”给定的名称,要么如果在给定的工作簿中找不到工作表名称,那么它将 return 一个具有给定名称的新工作表。这个方法可能看起来像……
Private Function GetWorksheet(wb As Excel.Workbook, name As String) As Excel.Worksheet
For Each ws In wb.Sheets
If ws.Name = name Then
Return ws
End If
Next
Dim newWS = wb.Worksheets.Add()
newWS.Name = name
Return newWS
End Function
上面的代码遍历给定工作簿中的所有工作表。如果找到与给定名称匹配的工作表名称,则该工作表将被 returned。如果未找到工作表名称,则会 returned 一个具有给定名称的新工作表。这将允许您将工作表命名为比“Sheet1”、“Sheet2”等更直观的名称。我们可以使用此方法获取现有工作表或为要添加到工作簿的每个网格创建新工作表。
接下来,第二个名为 AddSheetToWorkbook
的辅助方法需要一个工作簿、一个 DataGridView
和一个工作表名称...可能会使事情变得更容易。在此方法中,代码将 select 给定网格中的所有单元格。使用上述方法从给定的 (OPEN) 工作簿中获取具有给定工作表名称的工作表。然后将复制的单元格粘贴到工作表中。它可能看起来像……
Private Sub AddSheetToWorkbook(xlWorkBook As Excel.Workbook, dgv As DataGridView, wkSheetName As String)
dgv.SelectAll()
Dim dataObj As DataObject = dgv.GetClipboardContent()
If dataObj IsNot Nothing Then Clipboard.SetDataObject(dataObj)
Dim xlWorkSheet = GetWorksheet(xlWorkBook, wkSheetName)
Dim CR As Excel.Range = CType(xlWorkSheet.Cells(1, 1), Excel.Range)
CR.[Select]()
xlWorkSheet.PasteSpecial(CR, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, True)
End Sub
我们可以使用此方法将每个 DataGridView
添加到工作簿中的不同工作表。
最后,将所有这些放在一起可能如下所示。我使用了一些不同的方法,使用 Try/Catch/Finally
来确保 Excel COM objects 被正确处理,但是,在我的测试中,当前代码也有效。
该代码使用与当前代码相同的方法。使用 SaveFileDialog.
获取工作簿的文件名 创建一个新的 Excel 应用程序,添加工作簿,然后将两个网格添加到工作簿。每个网格都将位于一个单独的工作表上,并带有提供的工作表名称。文件已保存,Finally
COM
objects 已关闭并释放。
不清楚在当前发布的代码中“在哪里”调用了这段代码。在此示例中,代码是 运行 通过按表单上的按钮。
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim sfd As SaveFileDialog = New SaveFileDialog With {
.Filter = "Microsoft Excel 97-2003 Workbook (*.xls)|*.xls",
.FileName = NomTextBox.Text & "_" & PrenomTextBox.Text
}
If sfd.ShowDialog() = DialogResult.OK Then
Dim xlexcel As Excel.Application = Nothing
Dim xlWorkBook As Excel.Workbook = Nothing
Dim misValue As Object = Reflection.Missing.Value
Try
xlexcel = New Excel.Application()
xlWorkBook = xlexcel.Workbooks.Add()
AddSheetToWorkbook(xlWorkBook, DataGridView1, "Grid1")
AddSheetToWorkbook(xlWorkBook, DataGridView2, "Grid2")
xlWorkBook.SaveAs(sfd.FileName, Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue)
Catch ex As Exception
MessageBox.Show("Error: " + ex.Message)
Finally
If (xlWorkBook IsNot Nothing) Then
xlWorkBook.Close()
Runtime.InteropServices.Marshal.ReleaseComObject(xlWorkBook)
End If
If (xlexcel IsNot Nothing) Then
xlexcel.Quit()
Runtime.InteropServices.Marshal.ReleaseComObject(xlexcel)
End If
MessageBox.Show("Export Complete")
End Try
End If
End Sub
最后,我猜您不需要 Excel 文件中的 headers 列,因为 OS select all 和复制命令不会抓取网格列 header 文本。
我希望这是有道理的。