如何在C#中将HTML设置为剪贴板?

时间:2012-11-11 15:08:21

标签: c# .net html clipboard

我想在剪贴板上放置HTML格式的富文本,这样当用户粘贴到Word时,它将包含源HTML格式。

使用the Clipboard.SetText method不起作用。

另外,我希望如果用户粘贴到像Word这样的丰富编辑器中,它会粘贴格式化文本,如果它们粘贴到像记事本这样的普通编辑器中,它将粘贴纯文本。

5 个答案:

答案 0 :(得分:23)

设置HTML文本时,您需要提供一个标题,其中包含您实际要粘贴的html片段的附加信息,同时能够为其提供额外的样式:

Version:0.9
StartHTML:000125
EndHTML:000260
StartFragment:000209
EndFragment:000222
<HTML>
<head>
<title>HTML clipboard</title>
</head>
<body>
<!–StartFragment–><b>Hello!</b><!–EndFragment–>
</body>
</html>

使用标题(和正确的索引),使用Clipboard.SetText调用TextDataFormat.Html即可。

要处理HTML和纯文本粘贴,您不能使用Clipboard.SetText方法,因为它会在每次调用时清除剪贴板;您需要创建一个DataObject实例,使用HTML调用其SetData方法一次,使用纯文本调用一次,然后使用Clipboard.SetDataObject将对象设置为剪贴板。

<强>更新

有关详细信息和 ClipboardHelper 实施,请参阅“Setting HTML/Text to Clipboard revisited”。

答案 1 :(得分:3)

我找到了一些代码:https://www.experts-exchange.com/questions/21966855/Create-a-hyperlink-in-VB-net-copy-to-clipboard-Should-be-able-to-paste-hyperlink-in-Microsoft-Word-Excel.html

此代码处理更新开始和结束索引的问题。

转换为c#:

public void AddHyperlinkToClipboard(string link, string description)
{
    const string sContextStart = "<HTML><BODY><!--StartFragment -->";
    const string sContextEnd = "<!--EndFragment --></BODY></HTML>";
    const string m_sDescription = "Version:1.0" + Constants.vbCrLf + "StartHTML:aaaaaaaaaa" + Constants.vbCrLf + "EndHTML:bbbbbbbbbb" + Constants.vbCrLf + "StartFragment:cccccccccc" + Constants.vbCrLf + "EndFragment:dddddddddd" + Constants.vbCrLf;

    string sHtmlFragment = "<A HREF=" + Strings.Chr(34) + link + Strings.Chr(34) + ">" + description + "</A>";

    string sData = m_sDescription + sContextStart + sHtmlFragment + sContextEnd;
    sData = sData.Replace("aaaaaaaaaa", m_sDescription.Length.ToString().PadLeft(10, '0'));
    sData = sData.Replace("bbbbbbbbbb", sData.Length.ToString().PadLeft(10, '0'));
    sData = sData.Replace("cccccccccc", (m_sDescription + sContextStart).Length.ToString().PadLeft(10, '0'));
    sData = sData.Replace("dddddddddd", (m_sDescription + sContextStart + sHtmlFragment).Length.ToString().PadLeft(10, '0'));
    sData.Dump();
    Clipboard.SetDataObject(new DataObject(DataFormats.Html, sData), true );
}

答案 2 :(得分:1)

Arthur对标题是正确的,但重要的是要注意的是数据不会作为纯文本出现在剪贴板上。你必须使用CF_HTML。您可以在MSDN上阅读相关内容:http://msdn.microsoft.com/en-us/library/aa767917(v=vs.85).aspx 为了正确,你有一个CF_TEXT简单地显示:“你好!”,然后是带有HTML标题和数据的CF_HTML,如Arthur的例子所示。

答案 3 :(得分:1)

让我分享一个将剪贴板数据设置为 HTML 的助手,这是我刚刚为我的小项目 #DevComrade 提出的:


var dataObject = new DataObject();
dataObject.SetData(DataFormats.Html, ClipboardFormats.ConvertHtmlToClipboardData(html);
Host.SetClipboardDataObject(dataObject);

internal static class ClipboardFormats
{
    static readonly string HEADER = 
        "Version:0.9\r\n" +
        "StartHTML:{0:0000000000}\r\n" +
        "EndHTML:{1:0000000000}\r\n" +
        "StartFragment:{2:0000000000}\r\n" +
        "EndFragment:{3:0000000000}\r\n";

    static readonly string HTML_START =
        "<html>\r\n" +
        "<body>\r\n" +
        "<!--StartFragment-->";

    static readonly string HTML_END =
        "<!--EndFragment-->\r\n" +
        "</body>\r\n" +
        "</html>";

    public static string ConvertHtmlToClipboardData(string html)
    {
        var encoding = new System.Text.UTF8Encoding(encoderShouldEmitUTF8Identifier: false);
        var data = Array.Empty<byte>();

        var header = encoding.GetBytes(String.Format(HEADER, 0, 1, 2, 3));
        data = data.Concat(header).ToArray();

        var startHtml = data.Length;
        data = data.Concat(encoding.GetBytes(HTML_START)).ToArray();

        var startFragment = data.Length;
        data = data.Concat(encoding.GetBytes(html)).ToArray();

        var endFragment = data.Length;
        data = data.Concat(encoding.GetBytes(HTML_END)).ToArray();

        var endHtml = data.Length;

        var newHeader = encoding.GetBytes(
            String.Format(HEADER, startHtml, endHtml, startFragment, endFragment));
        if (newHeader.Length != startHtml)
        {
            throw new InvalidOperationException(nameof(ConvertHtmlToClipboardData));
        }

        Array.Copy(newHeader, data, length: startHtml);
        return encoding.GetString(data);
    } 
}

我使用了 thisthis 引用。另外,感谢@DaveyBoy 发现错误。

答案 4 :(得分:-1)

正如亚瑟(Arthur)所述,我在Setting HTML/Text to Clipboard revisited处使用了代码

我必须向标题添加换行符才能使其正常工作(在本例中为VB)

Private Const Header As String = "Version:0.9" & vbCrLf & "StartHTML:<<<<<<<<1" & vbCrLf & "EndHTML:<<<<<<<<2" & vbCrLf & "StartFragment:<<<<<<<<3" & vbCrLf & "EndFragment:<<<<<<<<4" & vbCrLf & "StartSelection:<<<<<<<<3" & vbCrLf & "EndSelection:<<<<<<<<4"

希望这会有所帮助