繁体   English   中英

如何创建字符串并将其分配到剪贴板,以便在粘贴时 MS Word 将其作为表格接受?

[英]How to create and assign a string to clipboard so that when pasted MS Word will accept it as a table?

我必须找到一种生成字符串的方法,以便在设置并粘贴到 Word 文档时显示一个表格。

我对此进行了一些研究,但似乎没有一个有效。 我尝试的一件事是生成一个 HTML 字符串,然后将其设置为剪贴板数据并将格式传递为 HTML。

string html = @"<html><body><table>
  <tr>
    <th>Month</th>
    <th>Savings</th>
  </tr>
  <tr>
    <td>January</td>
    <td>$100</td>
  </tr>
  </table></body></html>";

Clipboard.SetData(DataFormats.Html, html);

但它不起作用,当我尝试时,没有任何东西粘贴到 word doc 中。 然后当我将数据格式设置为文本(DataFormats.Text)时,它被粘贴但仅作为文本,而不是作为表格。

基本上,你需要知道的一切都在微软自己关于这个主题的文章中:如何使用 Win32 的剪贴板 API 复制和粘贴 HTML:

https://docs.microsoft.com/en-us/windows/win32/dataxchg/html-clipboard-format

(注意:在撰写本文时,有一点讽刺意味的是,一篇关于正确格式化剪贴板本身的 HTML 的文章本身就是 Markdown 和损坏的 HTML 的网格,所以我认为所有这些都修复了...损坏的 HTML 和......我最终基本上重写了这篇文章, 这是 PR )。


要通过 Windows 的剪贴板 API 传递 HTML,您需要做一些事情:

  • The entire HTML text must be structurally valid HTML (so you can still hang on to any Netscape-era HTML when everyone WAS SHOUTING ALL THE TIME BECAUSE HTML TAGS WERE ALL UPPERCASE and few bothered to ever use a </p> or </li> )。

    • ...但你不能做像<script><head></p>这样的事情。
    • 虽然像<span><div></div></span>这样的 HTML 在语法上有效且格式正确,但 HTML 本身不允许<span>成为<div>的父级,并要求浏览器分解外部<span>分成不同的兄弟姐妹和堂兄弟,并将单个<div>带到顶层 - 并且文档没有提到如果你尝试复制(或粘贴)“HTML”会发生什么 - 尽管我认为Windows 确实如此t 关心并且只是将其视为一个大字符串,但是可以与其他使用粘贴的HTML的应用程序(例如 Word、Excel 等)一起玩,因为这就是安全漏洞的开始方式。
    • 此外,Windows 和其他应用程序如何处理 HTML 的自定义元素功能也完全没有记录。
  • 然后,您需要生成一个 header,具有正确的参数和正确的格式,以使其正常工作 电脑太可怕了。

  • 当您传入单个大元素( <table> ,我假设?)时, <table>outerHTML可以是实际 HTML 片段的边界,该片段将(或者更确切地说,应该)由接收方复制应用。

    • 这个外部元素,片段,用 HTML 注释<!--StartFragment--><!--EndFragment-->
  • 只有现在您才能计算那些 header 参数的值(它们代表<!--Start/EndFragment-->边界的有意冗余表示)...

    • ...问题是将这些Start/EndFragment注释插入 HTML 会使消息更长会破坏任何先前计算的绝对偏移量。

因此, (Doug DeMuro 语音)是文本数据的模板,该模板代表 HTML 片段被放入 Windows 剪贴板:

Version:1.0
StartHTML:AAAA
EndHTML:BBBB
StartFragment:CCCC
EndFragment:DDDD
[StartSelection:CCCC
EndSelection:CCCC]
<HTML goes here>
  • 标题由简单的换行符分隔。 奇怪的是 MS 的文档说所有 3 种主要的换行样式都是允许的( \r\r\n\n ),

  • 最后 2 个标头/参数( StartSelectionEndSelection )是可选的(但是您必须既不提供也不能提供两者 - 仅提供两个Start/EndSelection参数之一会以未指定的方式破坏事情。

  • 现在这样做:

    1. 将该模板复制到一个新String中,并将完成的 HTML 直接粘贴在 header 的末尾,用一个换行符分隔。
    2. 看看上面那个header。 在顶部看到Version:1.0吗? 是的? 好的。 忽略它。
    3. 现在请参阅下面的StartHTML参数。 我们将最后计算。 暂时忽略它
    4. 接下来是EndHTML ,它是 HTML 文本本身结尾的绝对字节偏移量(从 header 的开头,而不是 HTML) - 基本上是消息长度
    5. StartFragment是表示片段本身的格式良好的 HTML 元素中的绝对字节偏移量(从标头的开头)到<
    • 插入的<!--Start/EndFragment-->注释必须被考虑在片段之外(即片段的原始 HTML 的String表示不会在任何地方包含这些注释)..
    1. EndFragment是绝对字节偏移量(从标头的开头)到片段的结尾。 这是一个排他的上限(所以如果StartFragment=100EndFragment=150则片段长度为 50 个字符,简单)。
      • 重要提示:请记住,由Start/EndFragment表示的文本运行必须是有效的有点“自包含”的元素。 所以你不能有一个在标签或其属性突然结束的片段 - 也不能从容器元素的许多文本节点中途开始......
      • ...但是,如果Start/EndSelection标头存在,则可以在人类可读文本中的任意点开始和结束(但相反,文档没有说明如果Start/EndSelection在元素的标签或属性内会发生什么,例如例子)。
  • 然后将这些计算的数字替换为下面的那些BBBB / CCCC /etc 占位符:但不要删除未使用的占位符:而是用前导数字'0'字符替换它们。

    • 别担心:在这种情况下(至少)任何前导零都不会被解释为强制八进制(base-8) integer 解析,
  1. 哦,差点忘了: go 回到顶部以计算StartHTML ,这是 HTML 文本开头的绝对字节偏移量(以及我假设<htm>中的开头'<' )。

所以你最终会得到这个:

string htmlInTheClipboardLooksLikeThis =
@"Version:1.0
StartHTML:0081
EndHTML:0263
StartFragment:0016
EndFragment:0126
<html>
<body>
<!--StartFragment--><table>
<tr>
<th>Month</th>
<th>Savings</th>
</tr>
<tr>
<td>January</td>
<td>$100</td>
</tr>
</table><!--EndFragment-->
</body>
</html>";

你只需要将它传递给SetText不是SetData )与TextDataFormat.Html

Clipboard.SetText( htmlInTheClipboardLooksLikeThis, TextDataFormat.Html );

只需在 Linqpad 中运行它,我们就可以直接粘贴到 Word 中……它确实将其导入为 Word 表格:

在此处输入图像描述

暂无
暂无

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

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