How to keep colors when copy-pasting from datagrid

2019-02-16 01:11发布

问题:

I use the following CellFormatting code to conditionally color rows in my datagridview.

private void SGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
    if (e.ColumnIndex == SGridView.Columns["Name"].Index )
    {
        DataGridViewRow row = SGridView.Rows[e.RowIndex];
        SBomRow BomRow = (SBomRow )row.DataBoundItem;
        switch (BomRow.UsageType())
        {
            case (UsageType.NE):
                break;
            case (UsageType.SV):
                e.CellStyle.BackColor = Color.OrangeRed;
                break;
            case (UsageType.Mix):
                e.CellStyle.BackColor = Color.LightGray;
                break;
            default:
                break;
        }
    }
}

When I copy paste from the datagridview to excel, coloring is lost. I know that data is added as HTML and CSV data to the clipboard when pasting, so it is probably impossible to keep coloring when pasting to excel. Is that true, or is there a way to keep colors when copy-pasting.

回答1:

I believe that DataGridView by default stores in the clipboard only tab delimited data without formatting

But you can write your custom Copy with Formatting function using the method, described in

http://www.tcx.be/blog/2005/copy-html-to-clipboard/

Just in case if you will want to ask a question how to handle copy event to write some custom code and put formatted HTML to clipboard, I would suggest using PreviewKeyDown event and write something like

if (e.KeyData.ToString() == "C, Control") {  your formatting code goes here  
} 


回答2:

I was able to set the colors by using a modified version of the code found here. First I changed the CopyHtmlToClipBoard() to a public static void method and place it in an Extension class. Next, when calling the code, I set a var to capture each cells color and then modified the html.AppendFormat()statement to include the color being passed. Here is a copy of the code used:

 public static void CopyHtmlToClipBoard(string html)
    {
        Encoding enc = Encoding.UTF8;

        string begin = "Version:0.9\r\nStartHTML:{0:000000}\r\nEndHTML:{1:000000}"
          + "\r\nStartFragment:{2:000000}\r\nEndFragment:{3:000000}\r\n";

        string html_begin = "<html>\r\n<head>\r\n"
          + "<meta http-equiv=\"Content-Type\""
          + " content=\"text/html; charset=" + enc.WebName + "\">\r\n"
          + "<title>HTML clipboard</title>\r\n</head>\r\n<body>\r\n"
          + "<!--StartFragment-->";

        string html_end = "<!--EndFragment-->\r\n</body>\r\n</html>\r\n";

        string begin_sample = String.Format(begin, 0, 0, 0, 0);

        int count_begin = enc.GetByteCount(begin_sample);
        int count_html_begin = enc.GetByteCount(html_begin);
        int count_html = enc.GetByteCount(html);
        int count_html_end = enc.GetByteCount(html_end);

        string html_total = String.Format(
          begin
          , count_begin
          , count_begin + count_html_begin + count_html + count_html_end
          , count_begin + count_html_begin
          , count_begin + count_html_begin + count_html
          ) + html_begin + html + html_end;

        DataObject obj = new DataObject();
        obj.SetData(DataFormats.Html, new MemoryStream(
          enc.GetBytes(html_total)));

        Clipboard.SetDataObject(obj, true);
    }


     private void copyAlltoClipboard()
    {

        var DataGridView1Counts = DataGridView1.Rows.Count;


        StringBuilder html = new StringBuilder();
        html.Append("<table>");

        if (DataGridView1Counts > 0)
        {
            //sets headers
            html.Append("<tr>");
            html.Append("<th> Name1 </th>");
            html.Append("<th> Name2 </th>");
            html.Append("<th> Name3 </th>");
            html.Append("<th> Name4 </th>");
            html.Append("<th> Name5 </th>");

            foreach (DataGridViewRow row in DataGridView1.Rows)
            {
                html.Append("<tr>");
                foreach (DataGridViewCell cell in row.Cells)
                {
                    var cellcolor = cell.Style.BackColor;
                    html.AppendFormat("<td bgcolor = " + cellcolor.Name + ">{0}</td>", cell.Value);
                }
                html.Append("</tr>");
            }
        }
        html.Append("</table>");
        Extensions.CopyHtmlToClipBoard(html.ToString());
    }