Datagridview - 将选定的单元格复制到新的 DataTable

我需要将数据从 DataGridView 导出到 Excel,但只能导出选定的单元格。DataGridView 绑定到 DataTable。我看过很多关于如何复制选定行的示例,但找不到关于如何仅将选定单元格复制到新 DataTable 中的示例。到目前为止,这是我尝试过的:


  //First, copy structure of DataTable into new one

  DataTable dt = ((DataTable)dgv.DataSource).Clone();


  //Then insert data into new datatable

  foreach (DataGridViewCell cell in dgv.SelectedCells)

  {

    //We get Index of column and row from bounded DataTable 

     int col_indx = ((DataTable)dgv.DataSource).Columns.IndexOf(dgv.Columns[cell.ColumnIndex].Name);

     int row_indx = ((DataTable)dgv.DataSource).Rows.IndexOf(((DataRowView)dgv.Rows[cell.RowIndex].DataBoundItem).Row);


  //First check if row already exists

  if (dt.Columns.Contains(dgv.Columns[cell.ColumnIndex].Name))

            {

                DataRow newrow = dt.NewRow();

                newrow[col_indx] = cell.Value;

                dt.Rows.InsertAt(newrow, row_indx);

            }

            else

            {

               dt.Rows[row_indx][cell_indx] = cell.Value;

            }    


  }

   dt.AcceptChanges();

这部分将数据插入到新的数据表中,但如果我从同一行中选择一些单元格,则在不同的行中。我怎样才能解决这个问题 ?


编辑:


 for (int i = 0; i < dgv.Rows.Count; i++)

 {

     dt.Rows.Add();

     for (int j = 0; j < dgv.ColumnCount; j++)

     {

        if (dgv.Rows[i].Cells[j].Selected == true)

        {

           dt.Rows[i][j] = dgv.Rows[i].Cells[j].Value;

        }

     }

  }

   dt.AcceptChanges();

这是我能实现的最接近的事情。它将选定的数据复制到新的 DataTable 中,但不幸的是它也保留了空行。因此,当我从例如第 3 行选择 Datagridview 中的单元格时,Excel 中的输出将前 2 行为空。我想避免这种情况,但是如何呢?...换句话说,我在 Datagridview 中选择的内容必须从第 1 行的新数据表开始,依此类推...


jeck猫
浏览 371回答 3
3回答

不负相思意

您为每一行添加一行。您必须为每个选定的行添加一行。试试这个&nbsp;int k=0;&nbsp;bool addRow;&nbsp;for (int i = 0; i < dgv.Rows.Count; i++)&nbsp;{&nbsp; &nbsp; &nbsp;addRow=true;&nbsp; &nbsp; &nbsp;for (int j = 0; j < dgv.ColumnCount; j++)&nbsp; &nbsp; &nbsp;{&nbsp; &nbsp; &nbsp; &nbsp; if (dgv.Rows[i].Cells[j].Selected == true)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(addRow){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dt.Rows.Add();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; addRow=false;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; k++;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dt.Rows[k-1][j] = dgv.Rows[i].Cells[j].Value;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp;}&nbsp; }&nbsp; &nbsp;dt.AcceptChanges();

慕田峪9158850

问题解决了。但这并不容易。首先,我必须创建一个与有界数据表具有相同结构的新数据表。然后将所有选定的单元格复制到该数据表中。最后,我创建了一个新的 DataTable,其中只有不为空的行,使用来自 Levitikon 的这个答案的 CopyToDataTable方法。这是完整的代码://First, copy structure of DataTable into new oneDataTable dt = ((DataTable)dgv.DataSource).Clone();//Add all selected cells into this DataTablefor (int i = 0; i < dgv.Rows.Count; i++)&nbsp;{&nbsp; &nbsp; &nbsp;dt.Rows.Add();&nbsp; &nbsp; &nbsp;for (int j = 0; j < dgv.ColumnCount; j++)&nbsp; &nbsp; &nbsp;{&nbsp; &nbsp; &nbsp; &nbsp; if (dgv.Rows[i].Cells[j].Selected == true)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dt.Rows[i][j] = dgv.Rows[i].Cells[j].Value;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp;}&nbsp; }&nbsp; &nbsp;dt.AcceptChanges();&nbsp;// Then create a new DataTable without blank rows&nbsp;DataTable final_dt = dt.Rows.Cast<DataRow>()&nbsp;.Where(row => !row.ItemArray.All(field => field is DBNull ||&nbsp;string.IsNullOrWhiteSpace(field.ToString()))).CopyToDataTable();现在,我在 DataGridView 中选择的所有内容都会添加到新的 DataTable 中,一旦我在 Excel 中导出此 DataTable,所有数据都会根据需要从第 0 行开始。如果有人知道更好/更短的解决方案,请告诉我。

慕少森

您正在遍历每个选定的单元格,并在指定的row_indx处创建/插入一个新行,而不检查这些单元格是否属于同一行,以及dt是否已经在row_indx处插入了一行。我建议检查您是否已经在row_indx处插入了一行,如果它已经插入该行并将选定的单元格添加到其中,如果它没有该行则创建一个新行并添加选定的单元格。
打开App,查看更多内容
随时随地看视频慕课网APP