Export Data Grid (datagridview) to Excel in VB.NET

Create the following method and pass it the DataGridView that you want to export.  This will export all grid contents (including column headers) to Excel and “freeze” the top row.

Note: The “prog_Progress” object is a ProgressBar I added to the application to display the progress of the export to the user.

[csharp]

private void ExportDataGridViewToExcel(DataGridView dgv)
{
// exit method if there are no records to export
if (dgv.RowCount == 0)
{
MessageBox.Show(“No data to export.”, “No Data”, MessageBoxButtons.OK, MessageBoxIcon.Stop);
return;
}

SaveFileDialog fd = new SaveFileDialog();

fd.OverwritePrompt = false;
fd.FileName = “Export-” + DateTime.Now.ToString(“yyyyMMdd.hhmm”) + “.xls”; // default file name
fd.Filter = “Excel (*.xls) |*.xls;*.xlsx”;

if (fd.ShowDialog() == DialogResult.OK) // only continue if user specified/selected a file
{
UpdateStatus(“Exporting data to Excel…”);

// create the Excel app
Microsoft.Office.Interop.Excel._Application xlApp = new Microsoft.Office.Interop.Excel.Application();

// create the Workbook
Microsoft.Office.Interop.Excel._Workbook xlWB = xlApp.Workbooks.Add();

// create the Worksheet
Microsoft.Office.Interop.Excel._Worksheet xlWS = (Microsoft.Office.Interop.Excel._Worksheet)xlWB.Worksheets[1];

try
{
// show the progress bar
prog_Progress.Visible = true;
prog_Progress.Style = ProgressBarStyle.Blocks;
prog_Progress.Maximum = dgv.RowCount – 1;

// export the column headers
for (int c = 0; c < dgv.ColumnCount; c++)
{
xlWS.Cells[1, c + 1] = dgv.Columns[c].HeaderText;
}

// bold and underline the first row
Microsoft.Office.Interop.Excel.Range rng = (Microsoft.Office.Interop.Excel.Range)xlWS.Rows[1];
rng.EntireRow.Font.Bold = true;
rng.EntireRow.Font.Underline = true;

// freeze the top row
xlApp.ActiveWindow.SplitRow = 1;
xlApp.ActiveWindow.FreezePanes = true;

// export the data in the DataGridView
for (int r = 0; r <= dgv.RowCount – 1; r++)
{
Application.DoEvents(); // prevent the app from “Not Responding”…
prog_Progress.Value = r; // update the Progress Bar

for (int c = 0; c <= dgv.ColumnCount – 1; c++)
{
xlWS.Cells[r + 2, c + 1] = dgv[c, r].Value;
}
}

xlWS.Columns.AutoFit(); // autofit the columns

xlWB.SaveAs(fd.FileName); // save the file

prog_Shares.Visible = false;

xlWB.Close();
xlWS = null;
xlWB = null;
xlApp.Quit();
fd = null;

MessageBox.Show(“Excel Workbook Created Successfully”, “Export Complete”, MessageBoxButtons.OK, MessageBoxIcon.Information);
UpdateStatus(“Export to Excel complete!”);
}
catch (Exception ex)
{
xlWB.SaveAs(fd.FileName); // save the file
xlApp.Quit(); // quit Excel
prog_Progress.Value = prog_Shares.Maximum;
MessageBox.Show(“Error exporting data to Excel.” + Environment.NewLine + ex.Message, “Export error”, MessageBoxButtons.OK, MessageBoxIcon.Error);
prog_Shares.Visible = false;
}
}
}

[/csharp]

Populate a DataGridView with SqlDataReader

In order to display the data in a SqlDataReader object in a DataGridView control, you first need to load the data into a DataTable object. The code below is in C# and the Connection String is for a SQL Server database connection.

[csharp]
using System.Data.SqlClient;

SqlConnection con = new SqlConnection();
SqlCommand cmd = new SqlCommand();
SqlDataReader dr;

// set the connection string
con.ConnectionString = “Data Source=SqlServerName;Initial Catalog=DbName;Integrated Security=True”
con.Open();

string SQL = “SELECT * FROM tbl_Users”;

// create the SQL command
cmd = new SqlCommand(SQL, con);

// execute the SQL
dr = cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection);

DataTable table = new DataTable();
table.Load(dr);

reader.Close();
reader.Dispose();
con.Close();
con.Dispose();
cmd.Dispose();
cmd = null;

// Display the data in the DataGridView control…
DataGridView1.DataSource = table;
[/csharp]

Copy Selected DataGridView Cells to Clipboard

To copy selected cells to the Clipboard without Column Headers:

If dg.GetClipboardContent Is Nothing Then

MessageBox.Show(“Nothing selected to copy to clipboard.”)

Else

Me.dg.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableWithoutHeaderText

Clipboard.SetDataObject(Me.dg.GetClipboardContent)

End If

 

To copy selected cells to the Clipboard with Column Headers requires a bit more work because there is a leading tab/column that needs to be removed:

If dg.GetClipboardContent Is Nothing Then

MessageBox.Show(“Nothing selected to copy to clipboard.”)

Else

Me.dg.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText

Dim clipData As String = dg.GetClipboardContent.GetText()

Dim lines As String() = Regex.Split(clipData, “rn”)

Dim newClipData As New StringBuilder

Dim tab As Char = vbTab

For Each line As String In lines

newClipData.Append(line.Substring(line.IndexOf(tab) + 1) + vbCrLf)

Next

Clipboard.SetText(newClipData.ToString(), TextDataFormat.Text)

End If

Move an unbound DataGridView row up or down via code (VB.NET)

Doing something as simple as moving an unbound DataGridView (dgv) row up or down via code really shouldn’t be as difficult of a task as Visual Studio makes it.

I started out by creating two buttons on a Windows Form called btn_Up and btn_Down, respectively.  I then created a single sub routine that would be passed in the number of rows (+1 or -1) that the current row should be moved.  For example, to move a row “up” in dgv, it’s row index will be one less than it currently is (before the move)

Private Sub btn_Up_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_Up.Click

        ‘If already on the first row, don’t try to move the row up

        If Me.dgv_FinishingScheduleColumns.CurrentCell.RowIndex = 0 Then

            Exit Sub

        End If

MoveRow(-1) ‘ move up in the datagridview (row index is 1 less)

End Sub

Private Sub btn_Down_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_Down.Click

‘If already on the bottom row, don’t try to move the row down

        If Me.dgv_FinishingScheduleColumns.CurrentCell.RowIndex = Me.dgv_FinishingScheduleColumns.RowCount – 1 Then

            Exit Sub

End If

MoveRow(1) ‘ move down in the datagridview (row index is 1 more)

End Sub

Private Sub MoveRow(ByVal i As Integer)

Try

If (Me.dgv.SelectedCells.Count > 0) Then

Dim curr_index As Integer = Me.dgv.CurrentCell.RowIndex

Dim curr_col_index As Integer = Me.dgv.CurrentCell.ColumnIndex

Dim curr_row As DataGridViewRow = Me.dgv.CurrentRow

Me.dgv.Rows.Remove(curr_row)

Me.dgv.Rows.Insert(curr_index + i, curr_row)

Me.dgv.CurrentCell = Me.dgv(curr_col_index , curr_index + i)

End If

Catch ex As Exception

‘ do nothing if error encountered while trying to move the row up or down

End Try

End Sub

In addition to moving the row that contains the selected cell up or down, the MoveRow sub routine also selects the related cell in its “new” location after it has been moved.  I kept trying to set the CurrentCell.Selected value, but in the end, I needed to actually specify what the CurrentCell actually was.

Happy programming!

Private Sub btn_Up_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_Up.Click
MoveRow(-1) ‘ move up in the datagridview (row index is 1 less)
End Sub
Private Sub btn_Down_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_Down.Click
MoveRow(1) ‘ move down in the datagridview (row index is 1 more)
End Sub
Private Sub MoveRow(ByVal i As Integer)
Try
If (Me.dg_Environments.SelectedCells.Count > 0) Then
Dim curr_index As Integer = Me.dg_Environments.CurrentCell.RowIndex
Dim curr_cell_index As Integer = Me.dg_Environments.CurrentCell.ColumnIndex
Dim curr_row As DataGridViewRow = Me.dg_Environments.CurrentRow
Me.dg_Environments.Rows.Remove(curr_row)
Me.dg_Environments.Rows.Insert(curr_index + i, curr_row)
Me.dg_Environments.CurrentCell = Me.dg_Environments(curr_cell_index, curr_index + i)
End If
Catch ex As Exception
‘ do nothing if error encountered while trying to move the row up or down
End Try
End Sub