为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
jeck猫 2022-12-31 10:27:34
我需要将数据从 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 行的新数据表开始,依此类推...
查看完整描述

3 回答

?
不负相思意

TA贡献1777条经验 获得超10个赞

您为每一行添加一行。您必须为每个选定的行添加一行。试试这个


 int k=0;

 bool addRow;

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

 {

     addRow=true;

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

     {

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

        {

            if(addRow){

                dt.Rows.Add();

                addRow=false;

                k++;

            }

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

        }

     }

  }

   dt.AcceptChanges();


查看完整回答
反对 回复 2022-12-31
?
慕田峪9158850

TA贡献1794条经验 获得超7个赞

问题解决了。但这并不容易。首先,我必须创建一个与有界数据表具有相同结构的新数据表。然后将所有选定的单元格复制到该数据表中。最后,我创建了一个新的 DataTable,其中只有不为空的行,使用来自 Levitikon 的这个答案的 CopyToDataTable方法。这是完整的代码:


//First, copy structure of DataTable into new one

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


//Add all selected cells into this DataTable

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();


 // Then create a new DataTable without blank rows

 DataTable final_dt = dt.Rows.Cast<DataRow>()

 .Where(row => !row.ItemArray.All(field => field is DBNull ||

 string.IsNullOrWhiteSpace(field.ToString()))).CopyToDataTable();

现在,我在 DataGridView 中选择的所有内容都会添加到新的 DataTable 中,一旦我在 Excel 中导出此 DataTable,所有数据都会根据需要从第 0 行开始。如果有人知道更好/更短的解决方案,请告诉我。


查看完整回答
反对 回复 2022-12-31
?
慕少森

TA贡献2019条经验 获得超9个赞

您正在遍历每个选定的单元格,并在指定的row_indx处创建/插入一个新行,而不检查这些单元格是否属于同一行,以及dt是否已经在row_indx处插入了一行。

我建议检查您是否已经在row_indx处插入了一行,如果它已经插入该行并将选定的单元格添加到其中,如果它没有该行则创建一个新行并添加选定的单元格。


查看完整回答
反对 回复 2022-12-31
  • 3 回答
  • 0 关注
  • 323 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信