将Excel数据粘贴到空白DataGridView中 - 索引超出范围异常

时间:2014-04-03 09:27:25

标签: c# excel winforms datagridview

我有一张excel表,内容如下:

enter image description here

所以,我想要实现的是从Excel中复制并将其粘贴到空白的DataGridView视图中。

这是我到目前为止的代码:

private void PasteClipboard(DataGridView myDataGridView)
{
    DataObject o = (DataObject)Clipboard.GetDataObject();
    if (o.GetDataPresent(DataFormats.Text))
    {
        string[] pastedRows = Regex.Split(o.GetData(DataFormats.Text).ToString().TrimEnd("\r\n".ToCharArray()), "\r\n");
        foreach (string pastedRow in pastedRows)
        {
            string[] pastedRowCells = pastedRow.Split(new char[] { '\t' });
            using (DataGridViewRow myDataGridViewRow = new DataGridViewRow())
            {
                for (int i = 0; i < pastedRowCells.Length; i++)
                    myDataGridViewRow.Cells[i].Value = pastedRowCells[i];

                myDataGridView.Rows.Add(myDataGridViewRow);
            }
        }
    }
}

代码运行时,我收到以下错误:

enter image description here

我是否正确地接近了这项任务?

8 个答案:

答案 0 :(得分:7)

经过一番挖掘,我发现我必须首先添加列,然后添加一个新行,获取新创建的行的行索引,然后设置单元格值。

这是更新后的代码:

DataObject o = (DataObject)Clipboard.GetDataObject();
if (o.GetDataPresent(DataFormats.Text))
{
    if (myDataGridView.RowCount > 0)
        myDataGridView.Rows.Clear();

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

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

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

            columnsAdded = true;
            continue;
        }

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

        using (DataGridViewRow myDataGridViewRow = myDataGridView.Rows[myRowIndex])
        {
            for (int i = 0; i < pastedRowCells.Length; i++)
                myDataGridViewRow.Cells[i].Value = pastedRowCells[i];
        }
    }
}

}

这里有效:

enter image description here

很高兴接受有关改善此事的批评和有用提示。 此代码非常慢......

答案 1 :(得分:3)

定义gridview列,如果不是,则必须先定义列。

private void PasteClipboard(DataGridView myDataGridView)
{
    DataObject o = (DataObject)Clipboard.GetDataObject();
    if (o.GetDataPresent(DataFormats.Text))
    {
        string[] pastedRows = Regex.Split(o.GetData(DataFormats.Text).ToString().TrimEnd("\r\n".ToCharArray()), "\r\n");
        foreach (string pastedRow in pastedRows)
        {
            string[] pastedRowCells = pastedRow.Split(new char[] { '\t' });
            using (DataGridViewRow myDataGridViewRow = new DataGridViewRow())
            {
                myDataGridViewRow = (DataGridViewRow) myDataGridView.RowTemplate.Clone();
                for (int i = 0; i < pastedRowCells.Length; i++)
                    myDataGridViewRow.Cells[i].Value = pastedRowCells[i];

                myDataGridView.Rows.Add(myDataGridViewRow);
            }
        }
    }
}

如果没有定义列

private void PasteClipboard(DataGridView myDataGridView)
{
    //Create COlumns in datagridView
    myDataGridView = new DataGridView();
    myDataGridView.Columns.Add("col1", "Col1");
    myDataGridView.Columns.Add("col2", "Col2");
    myDataGridView.Columns.Add("col3", "Col3");
    myDataGridView.Columns.Add("col4", "Col4");

    DataObject o = (DataObject)Clipboard.GetDataObject();
    if (o.GetDataPresent(DataFormats.Text))
    {
        string[] pastedRows = Regex.Split(o.GetData(DataFormats.Text).ToString().TrimEnd("\r\n".ToCharArray()), "\r\n");
        foreach (string pastedRow in pastedRows)
        {
            string[] pastedRowCells = pastedRow.Split(new char[] { '\t' });
            using (DataGridViewRow myDataGridViewRow = new DataGridViewRow())
            {
                myDataGridViewRow = (DataGridViewRow) myDataGridView.RowTemplate.Clone();
                for (int i = 0; i < pastedRowCells.Length; i++)
                    myDataGridViewRow.Cells[i].Value = pastedRowCells[i];

                myDataGridView.Rows.Add(myDataGridViewRow);
            }
        }
    }
}

答案 2 :(得分:2)

发布了一个非常好的解决方案here

但是,需要更改一行:

 if (dgv.Rows.Count < (r + rowsInClipboard.Length))
            dgv.Rows.Add(r + rowsInClipboard.Length - dgv.Rows.Count);

需要更改为:

 if (dgv.Rows.Count < (r + rowsInClipboard.Length))
            dgv.Rows.Add(r + rowsInClipboard.Length+1 - dgv.Rows.Count);

如果此行未更改,则粘贴的最后一行将不会传递给SQL。

答案 3 :(得分:2)

我知道这是几年之后,但我一直在寻找解决这个问题的方法,并找到了BASA对Latheesan代码的修改。它只是部分工作,所以修改它,我想为未来的浏览器添加这个解决方案:

private void Paste(DataGridView d)
    {
        DataObject o = (DataObject)Clipboard.GetDataObject();
        if (o.GetDataPresent(DataFormats.StringFormat))
        {
            string[] pastedRows = Regex.Split(o.GetData(DataFormats.StringFormat).ToString().TrimEnd("\r\n".ToCharArray()), "\r");
            int j = 0;
            try { j = d.CurrentRow.Index; } catch { }
            foreach (string pastedRow in pastedRows)
            {
                DataGridViewRow r = new DataGridViewRow();
                r.CreateCells(d, pastedRow.Split(new char[] { '\t' }));
                d.Rows.Insert(j, r);
                j++;
            }
        }
    }

答案 4 :(得分:1)

完美代码:(写入按钮)

DataObject o = (DataObject)Clipboard.GetDataObject();
if (o.GetDataPresent(DataFormats.Text))
{
    if (myDataGridView.RowCount > 0)
        myDataGridView.Rows.Clear();

    if (myDataGridView.ColumnCount > 0)
        myDataGridView.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++)
                myDataGridView.Columns.Add("col" + i, pastedRowCells[i]);

            columnsAdded = true;
            continue;
        }

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

        using (DataGridViewRow myDataGridViewRow = myDataGridView.Rows[j])
        {
            for (int i = 0; i < pastedRowCells.Length; i++)
                myDataGridViewRow.Cells[i].Value = pastedRowCells[i];
        }
        j++;
    }
}

Latheesan's code修改。

答案 5 :(得分:0)

如果您要处理Unicode,下面是粘贴到绑定到DataGridView的DataTable的代码

        DataObject o = (DataObject)Clipboard.GetDataObject();
        if (o.GetDataPresent(DataFormats.Text))
        {
            string[] pastedRows = Regex.Split(o.GetText().TrimEnd("\r\n".ToCharArray()), "\r\n");
            foreach (string pastedRow in pastedRows)
            {
                string[] pastedRowCells = pastedRow.Split(new char[] { '\t' });
                var temp = dt1.NewRow();
                for (int i = 0; i < pastedRowCells.Length; i++)
                    temp[i] = pastedRowCells[i];
                dt1.Rows.Add(temp);
            }
        }

答案 6 :(得分:-1)

我刚刚修改了@Latheesan's code,如下所示,这是最短版本。

DataObject o = (DataObject)Clipboard.GetDataObject();

if (o.GetDataPresent(DataFormats.Text))
{
    if (myDataGridView.Rows.Count > 0)
        myDataGridView.Rows.Clear();
    if (myDataGridView.Columns.Count > 0)
        myDataGridView.Columns.Clear();

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

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

            columnsAdded = true;
            continue;
        }

        myDataGridView.Rows.Add(pastedRowCells);

        //***You don't need following lines, use just above line. ***

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

        //using (DataGridViewRow myDataGridViewRow = myDataGridView.Rows[myRowIndex])
        //{
        //    for (int i = 0; i < pastedRowCells.Length; i++)
        //        myDataGridViewRow.Cells[i].Value = pastedRowCells[i];
        //}
    }
}

答案 7 :(得分:-1)

//列数Bug Bug Propered :: //

using System.Linq;

DataTable xDataTable = new DataTable();
DataObject XClipboardDat = (DataObject)Clipboard.GetDataObject();

if (XClipboardDat.GetDataPresent(DataFormats.Text))
{
    string[] XClipboardRows = Regex.Split(XClipboardDat.GetData(DataFormats.Text).ToString(), @"[\r\n]+").Where(y => !string.IsNullOrEmpty(y.ToString())).ToArray();

    IEnumerable<string[]> XDatRowCol = XClipboardRows.Select(xRow => Regex.Split(xRow, @"[\t]+").Where(y => !string.IsNullOrEmpty(y.ToString())).ToArray());

    int ColNum = XDatRowCol.Select(XDatRow => XDatRow.Length).ToArray().Max<int>();

    for (int i = 0; i < ColNum; i++) { xDataTable.Columns.Add(); }

    foreach(string[] XDatRow in XDatRowCol) { xDataTable.Rows.Add(XDatRow); }

    dataGridView2.DataSource = xDataTable;
 }
相关问题