2017-02-20 32 views
0

У меня есть код, который должен включать текст заголовка при экспорте в Excel.Экспорт в Excel с текстом заголовка

For i As Integer = 0 To DataGridView2.Rows.Count - 2 
    For j As Integer = 0 To DataGridView2.Columns.Count - 1 
     ' Excel index starts from 1,1. As first Row would have the Column headers, adding a condition check. 
     If cellRowIndex = 1 Then 
      worksheet.Cells(cellRowIndex, cellColumnIndex) = DataGridView2.Columns(j).HeaderText 
     Else 
      worksheet.Cells(cellRowIndex, cellColumnIndex) = DataGridView2.Rows(i).Cells(j).Value 
     End If 
     cellColumnIndex += 1 
    Next 
    cellColumnIndex = 1 
    cellRowIndex += 1 
Next 

Однако этот код заменяет первую строку данных текстом заголовка вместо того, чтобы вставлять его выше. Если я удалю оператор If, который извлекает текст заголовка, я получаю все строки, но я не получаю текст заголовка.

For i As Integer = 0 To DataGridView2.Rows.Count - 2 
    For j As Integer = 0 To DataGridView2.Columns.Count - 1 
     worksheet.Cells(cellRowIndex, cellColumnIndex) = DataGridView2.Rows(i).Cells(j).Value 
     cellColumnIndex += 1 
    Next 
    cellColumnIndex = 1 
    cellRowIndex += 1 
Next 

Любые идеи о том, как это решить?

ответ

1

После трассировки кода ясно, у вас возникли проблемы индексации в двух for петель. Похоже, что в коде, который вы указали, отсутствует первая строка данных.

Как прокомментировал:

этот код заменяет первую строку данных с текстом заголовка вместо вставки его выше ...

Это не правильно, это не заменяет строка просто пропускает первую строку данных в DataGridView. Ниже приведен ваш код.

For i As Integer = 0 To DataGridView1.Rows.Count - 2 
    For j As Integer = 0 To DataGridView1.Columns.Count - 1 
    If cellRowIndex = 1 Then 
     worksheet.Cells(cellRowIndex, cellColumnIndex) = DataGridView1.Columns(j).HeaderText 
    Else 
     worksheet.Cells(cellRowIndex, cellColumnIndex) = DataGridView1.Rows(i).Cells(j).Value 
    End If 
    cellColumnIndex += 1 
    Next 
    cellColumnIndex = 1 
    cellRowIndex += 1 
Next 

В основном это петли через строки, а затем столбцы. Проблема заключается в заявке If и индексе i. В этом заявлении If вы проверяете, действительно ли это первый раз, чтобы получить заголовки. Если в первый раз вы пишете заголовки, чтобы преуспеть и продолжить. Это собирается пропустить первую строку данных, так как переменная i цикла используются в качестве индекса в DataGridView строки с заданием:

worksheet.Cells(cellRowIndex, cellColumnIndex) = DataGridView1.Rows(i).Cells(j).Value 

При входе в j петли в первый раз вокруг i равно нуль (0) , Проверка производится с помощью cellRowIndex, чтобы определить, нужно ли выводить заголовки. В этом случае они ... выводятся заголовки, затем выходят из этого if и возвращаются к следующему заголовку. Когда все заголовки выводятся, вы выходите из цикла j и возвращаете петлю до i. Это увеличит i до 1 и введите цикл j ... Поскольку i уже был 0, когда выведены заголовки, мы пропустим/пропустим строку 0 в DataGridView. Я надеюсь в этом есть смысл.

Простое решение для того, что вы должны были бы просто начать i на -1 с:

For i As Integer = -1 To DataGridView1.Rows.Count - 2 

Это позволит решить проблему, которую вы испытываете, однако код не легко следовать.Я рекомендую использовать цикл foreach для прокрутки строк DataGridView и разделения вывода столбца на выходе строк. Это создает две петли, но первый цикл будет только петля один раз, чтобы добавить заголовки. Следующий цикл проходит через все строки. Это упростит обработку индексации и упростит чтение в будущем.

For Each column In DataGridView1.Columns 
    worksheet.Cells(1, column.Index + 1).Value = column.Name 
Next 

Dim rowIndex = 2 
For Each row As DataGridViewRow In DataGridView1.Rows 
    If Not row.IsNewRow Then 
    For colIndex As Integer = 0 To DataGridView1.Columns.Count - 1 
     worksheet.Cells(rowIndex, colIndex + 1).Value = row.Cells(colIndex).Value.ToString 
    Next 
    End If 
    rowIndex += 1 
Next 

Надеюсь, это поможет.

+0

Вау, это должен быть самый полный и хорошо объясненный ответ, который я видел до сих пор в Stackoverflow. Спасибо! Я даже начинаю понимать, что я здесь делаю :) Вы упомянули две петли foreach; Должен ли я разместить ваш цикл до существующего цикла? – LarsS

+0

Извините, мой плохой. Я вижу, что в вашем коде есть две петли. Too triggerhappy ...;) – LarsS

+0

Последний бит кода должен сделать трюк. Первый цикл для заголовков, следующий для строк. – JohnG

2

Ниже код создает файл Excel с заголовком из DataGridView. Я тестировал его в Visual Studio 2010. Сначала вам нужно добавить ссылку на сборку Microsoft Office.

  • Microsoft.Office.Interop.Excel (версия - 12.0.0.0)

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.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.Application 
    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("C:\vbToexcel.xlsx") 
    xlWorkBook.Close() 
    xlApp.Quit() 
    
    releaseObject(xlApp) 
    releaseObject(xlWorkBook) 
    releaseObject(xlWorkSheet) 
    
    MsgBox("File successfully created - C:\vbToexcel.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 
    
+0

Вы проследили свой ответ? Эта петля третьего цикла «k» выглядит очень странно. Простая трассировка показывает, что код записывает одни и те же данные снова и снова ... один раз для столбца 1, дважды для столбца 2, три раза для столбца 3 и т. Д. Вы можете проверить это. – JohnG

+0

Я пробовал это и получил исключение для цикла k. – LarsS

+0

Привет, Джон, я проследил код. На самом деле мы копируем все ячейки значений Grid по ячейкам и по строке, чтобы повторять цикл «k», но не повторяя одни и те же данные снова и снова. – Sandy