【问题标题】:Export data from datagridview to MS Word table - error将数据从 datagridview 导出到 MS Word 表 - 错误
【发布时间】:2021-09-24 07:54:35
【问题描述】:

我尝试从 datagridview 获取数据到 MS word 表,但我收到一条错误消息:索引超出范围。它必须是非/负的...... 任何人都可以帮助我吗? 这是我的代码的一部分(我使用 Microsoft.Office.Interop.Word)

            Table thirdTable = document.Tables.Add(para3.Range,dataGridViewObjednavka.RowCount+1, dataGridViewObjednavka.ColumnCount, ref missing, ref missing);
            {
                //thirdTable.Cell(1, 1).Range.Text = "Položka";
                //thirdTable.Cell(1, 2).Range.Text = "Špecifikácia / materiál";
                //thirdTable.Cell(1, 3).Range.Text = "Objednávacie číslo";
                //thirdTable.Cell(1, 4).Range.Text = "Množstvo";
                {

                    int rowIndex = 0;
                    int colIndex = 0;

                    foreach (DataGridViewRow row in dataGridViewObjednavka.Rows)
                    {
                        {
                            foreach (DataGridViewColumn col in dataGridViewObjednavka.Columns)
                            {
                                thirdTable.Cell(rowIndex, colIndex).Range.Text = Convert.ToString(dataGridViewObjednavka.Rows[rowIndex].Cells[colIndex].Value);
                                colIndex++;
                            }
                            rowIndex++;
                        }
                    }

                }
            }

【问题讨论】:

    标签: c# indexing datagridview ms-word export


    【解决方案1】:

    在 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)
    

    资源:

    【讨论】:

    • 感谢您的回复。我试着把int值改成1,但还是有问题....我真的搞不定
    • 我已经更新了帖子。 colIndex 每行需要重新初始化为 1。
    • 再次感谢,但即使在使用您的代码后,我仍然收到索引错误消息。我是初学者,我只是把它作为一种爱好。真不知道错在哪里
    • 我已经用完整的工作解决方案更新了代码。它已经过测试。随意修改它以满足您的需求。
    猜你喜欢
    • 1970-01-01
    • 2018-02-14
    • 2014-06-28
    • 1970-01-01
    • 1970-01-01
    • 2011-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多