从 DataGridView 粘贴到 Excel

本文关键字:Excel DataGridView | 更新日期: 2023-09-27 18:31:35

我想从dataGridView复制一个单元格区域,然后将该数据粘贴到MS Excel中。 我能够复制数据并粘贴到 MS Word 或记事本中,但不能 excel。 有很多从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");
            }
        }
    }
}

有没有办法粘贴到 excel 中? 我一直在努力寻找解决方案。

编辑

它出现在尝试使用dataGridView的其他一些程序后,默认情况下,您可以在dataGridView中选择一组单元格后复制并粘贴到excel或其他程序。 我现在无法弄清楚是 DGV 中不支持的数据还是我在属性管理器中更改的 DGV 属性,或者我只需要关闭并重新打开 excel,因为存在一些错误。

从 DataGridView 粘贴到 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());

备注:Selection是我的网格对突出显示内容的引用,this是用于获取单元格中数据的单元格引用。

基本上,它试图构建一个文本块

,如下所示:
R1C1'tR1C2'tR1C3'tR1C4'n
R2C1'tR2C2'tR2C3'tR2C4'n
R3C1'tR3C2'tR3C3'tR3C4'n

制表符 (''t) 指示它向右移动一列,换行符 (') 指示它向下移动一行。 这是一种非常标准的格式。 如果您在那里复制并粘贴到网格中,Excel 会为您提供什么。

好吧,当我不断寻找时,我最终找到了答案。

如果我将Clipboard.SetDataObject(d);更改为Clipboard.SetData(DataFormats.Html, d);这允许我将选定的单元格范围粘贴到 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;    
    }    
}

您可以使用此自定义控件。

为什么不简单地这样做 [ 无需检查剪贴板,因为您实际执行 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());               
        }
    }