简体   繁体   English

从 DataGridView 粘贴到 Excel

[英]Paste to Excel From DataGridView

I would like to copy a region of cells from a dataGridView and then paste that data into MS Excel.我想从 dataGridView 复制一个单元格区域,然后将该数据粘贴到 MS Excel 中。 I am able to copy data and paste into MS Word or Notepad but not excel.我可以复制数据并粘贴到 MS Word 或记事本中,但不能粘贴到 excel 中。 There are lots of examples of copying from Excel and Pasting into a DataGridView but not the other way around.有很多从 Excel 复制并粘贴到 DataGridView 的示例,但反之则不然。

private void frm_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Control && e.KeyCode == Keys.C)
    {
        this.dataGridView1.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableWithoutHeaderText;

        if (this.dataGridView1.GetCellCount(DataGridViewElementStates.Selected) > 0)
        {
            try
            {
                DataObject d = dataGridView1.GetClipboardContent();
                Clipboard.SetDataObject(d);
            }

            catch (System.Runtime.InteropServices.ExternalException)
            {
                MessageBox.Show("Could Not Copy To Clipboard");
            }
        }
    }
}

Is there some way to paste into excel?有什么方法可以粘贴到excel中吗? I have struggled to find a solution.我一直在努力寻找解决方案。

Edit编辑

It appears after trying some other programs with dataGridViews that you can by default copy and paste to excel or other programs after selecting a group of cells in dataGridView.在尝试使用 dataGridViews 尝试其他一些程序后出现,默认情况下,您可以在选择 dataGridView 中的一组单元格后复制并粘贴到 Excel 或其他程序。 I can't figure out right now if it was unsupported data in the DGV or properties of the DGV that I changed in the properties manager or I just needed to close and re-open excel because there was some error.我现在无法确定是 DGV 中不受支持的数据还是我在属性管理器中更改的 DGV 属性,或者我只需要关闭并重新打开 excel 因为有一些错误。

I can't say how this will line up with your grid, but here's an example of putting formatted text on the clipboard.我不能说这将如何与您的网格对齐,但这里有一个将格式化文本放在剪贴板上的示例。 This was written with the intent of pasting into Excel:这是为了粘贴到 Excel 中而编写的:

StringBuilder sb = new StringBuilder();
for (Int32 r = Selection.r1; r <= Selection.r2; r++)
{
    if (Rows[r].Visible)
    {
        if (!String.IsNullOrEmpty(sb.ToString()))
            sb.Append(Environment.NewLine);
        for (Int32 c = Selection.c1; c <= Selection.c2; c++)
        {
            if (!sb.ToString().EndsWith(Environment.NewLine) &&
                !String.IsNullOrEmpty(sb.ToString()) &&
                !sb.ToString().EndsWith("\t"))
                sb.Append("\t");
            if (String.IsNullOrEmpty(this[r, c] as String))
                sb.Append(" ");
            else
                sb.Append(this[r, c].ToString());
        }
    }
}

if (sb.Length > 0)
    ClipboardEx.SetTextThreadSafe(sb.ToString());

Note: Selection is my grid's reference to what is highlighted, and this is a cell reference to get to data in a cell.注意: Selection是我的网格对突出显示内容的引用, this是获取单元格中数据的单元格引用。

Basically, it's trying to construct a text block something like this:基本上,它试图构建一个像这样的文本块:

R1C1\tR1C2\tR1C3\tR1C4\n
R2C1\tR2C2\tR2C3\tR2C4\n
R3C1\tR3C2\tR3C3\tR3C4\n

The tabs (\\t) tell it to move right a column, the newlines (\\n) to move down a row.选项卡 (\\t) 告诉它向右移动一列,换行符 (\\n) 告诉它向下移动一行。 It's a pretty standard format.这是一个非常标准的格式。 What Excel would give you if you were copying there and pasting into your grid.如果你在那里复制并粘贴你的网格中,Excel 会给你什么。

Well I ended up finding the answer as I kept searching.好吧,我最终在不断寻找的过程中找到了答案。

If I change Clipboard.SetDataObject(d);如果我改变Clipboard.SetDataObject(d); to Clipboard.SetData(DataFormats.Html, d);Clipboard.SetData(DataFormats.Html, d); this allows me to paste selected cell ranges to excel.这允许我将选定的单元格范围粘贴到 excel。

public class MyDataGridView : DataGridView    
{    
    [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]    
    protected override bool ProcessDataGridViewKey(KeyEventArgs e)    
    {    
        switch (e.KeyCode)    
        {    
            case Keys.Insert:    
            case Keys.C:    
                return this.ProcessInsertKey(e.KeyData);    
            default:    
                break;    
        }    
        return base.ProcessDataGridViewKey(e);    
    }    

    [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]    
    protected new bool ProcessInsertKey(Keys keyData)    
    {    
        if ((((keyData & (Keys.Alt | Keys.Control | Keys.Shift)) == Keys.Control) ||    
            (((keyData & (Keys.Alt | Keys.Control | Keys.Shift)) == (Keys.Control | Keys.Shift))    
            && ((keyData & Keys.KeyCode) == Keys.C)))    
            && (this.ClipboardCopyMode != DataGridViewClipboardCopyMode.Disable))    
        {    
            DataObject clipboardContent = this.GetClipboardContent();    
            if (clipboardContent != null)    
            {     
                Clipboard.SetText(clipboardContent.GetData(DataFormats.UnicodeText).ToString());    
                return true;    
            }    
        }    
        return false;    
    }    
}

you can use this Custom Control.您可以使用此自定义控件。

Why not simply do this [ no need to check clipboard since you actually doing the CTRL-C ]为什么不简单地执行此操作 [无需检查剪贴板,因为您实际上是在执行 CTRL-C ]

private void frm_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Control && e.KeyCode == Keys.C)
        {
            dataGridView1.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableWithoutHeaderText;
            dataGridView1.SelectAll();
            Clipboard.SetDataObject(dataGridView1.GetClipboardContent());               
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM