在 Word 中,索引是从 1 开始的,而不是从零开始的。行或列的最小索引是 1。此外,colIndex 需要为每一行重新初始化为 1。在 DataGridView 中,最后一行可能是新行并且不包含任何数据。最后一行是一个(空的)新行,跳过它。
以下代码从 DataGridView 获取数据并创建一个 Word 文档。在 Word 文档中,添加了三个段落。创建具有所需行数和列数的表,并将数据填充到表中。完成后,word文档被保存。下面的代码已经过测试。
注意:如果您指定的文件名已经存在,则会抛出异常。如果您愿意,可以更改此行为。
向您的项目添加模块
- 在VS菜单中,点击Project
- 选择添加模块...(名称:HelperWord.vb)
- 点击添加
Helper.vb
'Pre-requisite: MS Word installed
'
'Add Reference
'Project => Add Reference => COM => Microsoft Word xx.x Object Library (ex: Microsoft Word 16.0 Object Library)
'
'https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.datagridviewcell.formattedvalue?view=netframework-4.8#System_Windows_Forms_DataGridViewCell_FormattedValue
Imports System.IO
Imports Word = Microsoft.Office.Interop.Word
Module HelperWord
Public Sub CreateWordDocFromDataGridView(ByVal dgv As DataGridView, ByVal filename As String)
Dim dgvUsableRowCount As Integer = 0
Dim documents As Word.Documents = Nothing
Dim doc As Word.Document = Nothing
Dim errMsg As String = String.Empty
Dim isVisible As Boolean = True 'Word visibility; if True, shows Word; if False, hides Word
Dim oEndOfDoc = "\endofdoc" '\endofdoc is a predefined bookmark
Dim oMissing As Object = System.Reflection.Missing.Value
Dim para1 As Word.Paragraph = Nothing
Dim para2 As Word.Paragraph = Nothing
Dim para3 As Word.Paragraph = Nothing
Dim para3Tbl As Word.Table = Nothing
Dim wordApp As Word.Application = Nothing
Try
If File.Exists(filename) Then
'if file already exists, throw an exception
'this prevents an existing file from being overwritten
Throw New Exception("File already exists (" & filename & ")")
End If
'last row of DataGridView may be a new row; if so, skip it as it doesn't contain any data
'set the value of the last index in the DataGridView that we're interested in
If dgv.Rows(dgv.Rows.Count - 1).IsNewRow Then
'set value - ignore the last row in the DataGridView since it doesn't contain any data
dgvUsableRowCount = dgv.Rows.Count - 1
Else
'set value - all DataGridView rows contain data
dgvUsableRowCount = dgv.Rows.Count
End If
'if no data exists in the DataGridView, display message and return
If dgvUsableRowCount <= 0 Then
MessageBox.Show("No data exists in the DataGridView", "No Data Exists", MessageBoxButtons.OK, MessageBoxIcon.Information)
Return
End If
'create new instance
wordApp = New Word.Application()
'suppress displaying alerts (such as prompting to overwrite existing file)
wordApp.DisplayAlerts = False
'set Word visibility
wordApp.Visible = isVisible
'create new document
doc = wordApp.Documents.Add()
doc.Activate()
'create paragraphs
para1 = doc.Paragraphs.Add() 'add paragraph
para2 = doc.Paragraphs.Add() 'add paragraph
para3 = doc.Paragraphs.Add() 'add paragraph
'add table
para3Tbl = doc.Tables.Add(para3.Range, dgvUsableRowCount, dgv.Columns.Count)
'set table properties
para3Tbl.BottomPadding = wordApp.InchesToPoints(0.01F) 'use "f" for floating-point number
para3Tbl.TopPadding = wordApp.InchesToPoints(0.01F) 'use "f" for floating-point number
para3Tbl.Borders.InsideLineStyle = Word.WdLineStyle.wdLineStyleSingle 'border between columns/rows
para3Tbl.Borders.OutsideLineStyle = Word.WdLineStyle.wdLineStyleSingle 'border around table
'Debug.WriteLine("dgv row count: " & dgv.Rows.Count & " column count: " & dgv.Columns.Count)
'since index starts at 0, the last index is count - 1
For dgvRowIndex As Integer = 0 To dgvUsableRowCount - 1
'DataGridView uses zero-based index
'Word uses one-based index
Dim wordRowIndex As Integer = dgvRowIndex + 1 'add 1
'Debug.WriteLine("\n wordRowIndex: " & wordRowIndex)
'since index starts at 0, the last index is count - 1
For dgvColIndex As Integer = 0 To dgv.Columns.Count - 1
'DataGridView uses zero-based index
'Word uses one-based index
Dim wordColIndex As Integer = dgvColIndex + 1 'add 1
'Debug.WriteLine("wordColIndex: " & wordColIndex)
Dim value As String = String.Empty
If dgv.IsCurrentCellDirty Then
value = dgv.Rows(dgvRowIndex).Cells(dgvColIndex).GetEditedFormattedValue(dgvRowIndex, DataGridViewDataErrorContexts.Formatting).ToString()
Else
value = dgv.Rows(dgvRowIndex).Cells(dgvColIndex).FormattedValue.ToString()
End If
If Not String.IsNullOrEmpty(value) Then
'populate table cell
para3Tbl.Cell(wordRowIndex, wordColIndex).Range.Text = value
End If
Next
Next
If Not String.IsNullOrEmpty(filename) Then
Try
'save document
'doc.SaveAs(filename, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing)
doc.SaveAs2(filename, Word.WdSaveFormat.wdFormatXMLDocument, CompatibilityMode:=Word.WdCompatibilityMode.wdWord2013)
Catch ex As Exception
errMsg = "Error (CreateWordDocFromDataGridView) - " & ex.Message
Debug.WriteLine(errMsg)
Throw ex 're-throw error
End Try
End If
Catch ex As Exception
Debug.WriteLine("Error () - " & ex.Message)
Throw ex
Finally
If doc IsNot Nothing Then
doc.Close()
doc = Nothing
End If
If wordApp IsNot Nothing Then
Dim oFalse As Object = False
wordApp.Quit(oFalse, oFalse, oFalse)
'release all resources
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(wordApp)
wordApp = Nothing
End If
End Try
End Sub
End Module
用法:
'write file to Documents folder (ex: C:\Users\<username>\Documents\TestWordDoc.docx)
Dim filename As String = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "TestWordDoc.docx")
HelperWord.CreateWordDocFromDataGridView(dataGridViewObjednavka, filename)
资源: