【问题标题】:Pasting Data from Excel to DataGridView将数据从 Excel 粘贴到 DataGridView
【发布时间】:2019-07-08 13:54:50
【问题描述】:

我正在尝试使用 C# 将数据从 excel 粘贴到我的数据网格视图中。我在网上找到了一些有效的代码,但是我的数据网格视图的标题正在填充粘贴数据的第一行(如下面的屏幕截图所示)。

如果可能,我想让列标题为空并在数据网格视图行中写入数据。在此先感谢您,请在下面找到正在使用的代码和屏幕截图。

private void btnPaste_Click(object sender, EventArgs e)
    {
        DataObject o = (DataObject)Clipboard.GetDataObject();
        if (o.GetDataPresent(DataFormats.Text))
        {
            if (dgvAuthG.RowCount > 0)
                dgvAuthG.Rows.Clear();

            if (dgvAuthG.ColumnCount > 0)
                dgvAuthG.Columns.Clear();

            bool columnsAdded = false;
            string[] pastedRows = Regex.Split(o.GetData(DataFormats.Text).ToString().TrimEnd("\r\n".ToCharArray()), "\r\n");
            int j = 0;
            foreach (string pastedRow in pastedRows)
            {
                string[] pastedRowCells = pastedRow.Split(new char[] { '\t' });

                if (!columnsAdded)
                {
                    for (int i = 0; i < pastedRowCells.Length; i++)
                        dgvAuthG.Columns.Add("col" + i, pastedRowCells[i]);

                    columnsAdded = true;
                    continue;
                }

                dgvAuthG.Rows.Add();
                int myRowIndex = dgvAuthG.Rows.Count - 1;

                using (DataGridViewRow myDataGridViewRow = dgvAuthG.Rows[j])
                {
                    for (int i = 0; i < pastedRowCells.Length; i++)
                        myDataGridViewRow.Cells[i].Value = pastedRowCells[i];
                }
                j++;
            }
        }
        dgvAuthG.Columns.RemoveAt(0);
        btnFormat.Enabled = true;
        btnFormatWay4.Enabled = true;
    }

enter image description here

【问题讨论】:

    标签: c# arrays string datagridview header


    【解决方案1】:

    您的代码正在将数据添加到列标题中...

    dgvAuthG.Columns.Add("col" + i, pastedRowCells[i]);
    

    …第二个参数是标题文本。我不确定你在这里期待什么。如果您希望列标题为“空”,则不要像代码那样添加文本。

    我强烈建议您将向网格中添加列与添加行的循环分开。这只会使循环代码同时添加行的复杂和不必要的。您“知道”您只会运行该代码(添加列)一次。因此,我建议您在开始添加行之前添加列。

    问题是我们必须读取其中一行才能获得列数。因此,如果我们在开始添加行之前拥有该列号,这将显得很有用,然后我们还可以使用它来循环遍历每行中的单元格。您只需执行一次,它可能如下所示。

    int totCols = pastedRows[0].Split(new char[] { '\t' }).Length;
    

    现在您有了网格的列数,添加列的简单循环应该可以工作了。

    for (int i = 0; i < totCols; i++) {
      dgvAuthG.Columns.Add("col" + i, "col" + i);
    }
    

    这将负责将列添加到网格中,并且肯定会使遍历行更容易且更简单。

    不过,在此之前,我猜您可能需要重新考虑“检查”网格是否有任何现有的列或行。现有的列数很可能与“剪贴板”中的列数不匹配。因此,检查是没有意义的……只需删除所有列并重新开始。否则几乎肯定会崩溃。

    最后,我使用了不同的方法来添加行。基本上,代码获取新行的索引并通过循环单元格来添加值。将所有这些放在一起可能如下所示。

    private void button1_Click(object sender, EventArgs e) {
      DataObject o = (DataObject)Clipboard.GetDataObject();
      if (o.GetDataPresent(DataFormats.Text)) {
        dgvAuthG.Columns.Clear();
        string[] pastedRows = Regex.Split(o.GetData(DataFormats.Text).ToString().TrimEnd("\r\n".ToCharArray()), "\r\n");
        int totCols = pastedRows[0].Split(new char[] { '\t' }).Length;
        for (int i = 0; i < totCols; i++) {
          dgvAuthG.Columns.Add("col" + i, "col" + i);
        }
        string[] pastedRowCells;
        int newRowIndex;
        foreach (string pastedRow in pastedRows) {
          pastedRowCells = pastedRow.Split(new char[] { '\t' });
          newRowIndex = dgvAuthG.Rows.Add();
          for (int i = 0; i < totCols; i++) {
            dgvAuthG.Rows[newRowIndex].Cells[i].Value = pastedRowCells[i];
          }
        }
      }
      //dgvAuthG.Columns.RemoveAt(0);
      //btnFormat.Enabled = true;
      //btnFormatWay4.Enabled = true;
    }
    

    希望对您有所帮助。

    【讨论】: