简体   繁体   English

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

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

I have to find a way to generate a string so that when set and then pasted to a Word document it will display a table.我必须找到一种生成字符串的方法,以便在设置并粘贴到 Word 文档时显示一个表格。

I did some research about this, but none of them seem to work.我对此进行了一些研究,但似乎没有一个有效。 One of the things I tried was to generate a string of HTML, then set it as the clipboard data and pass format as HTML.我尝试的一件事是生成一个 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);

but it did not work, nothing was pasted to word doc when I tried.但它不起作用,当我尝试时,没有任何东西粘贴到 word doc 中。 And then when I set Data format as text (DataFormats.Text) it was pasted but only as text, not as a table.然后当我将数据格式设置为文本(DataFormats.Text)时,它被粘贴但仅作为文本,而不是作为表格。

Basically, everything you need to know is in Microsoft's own article on this very topic: how to use Win32's Clipboard API to copy and paste HTML:基本上,你需要知道的一切都在微软自己关于这个主题的文章中:如何使用 Win32 的剪贴板 API 复制和粘贴 HTML:

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

(Note: at the time of writing, there's a small irony in that an article about correctly formatting HTML for the clipboard itself is itself a mesh of Markdown and broken HTML... so I thought I'd act all civic for once and fix the broken HTML and... I ended up basically rewriting the article, here's the PR ). (注意:在撰写本文时,有一点讽刺意味的是,一篇关于正确格式化剪贴板本身的 HTML 的文章本身就是 Markdown 和损坏的 HTML 的网格,所以我认为所有这些都修复了...损坏的 HTML 和......我最终基本上重写了这篇文章, 这是 PR )。


To pass HTML through Windows' Clipboard API, you need to do a few things:要通过 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> ). 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> )。

    • ...but you can't do things like <script><head></p> . ...但你不能做像<script><head></p>这样的事情。
    • While HTML like <span><div></div></span> is syntactically valid and well-formed, HTML itself doesn't allow <span> to parent a <div> and requires browsers to break-up the outer <span> into separate siblings and cousins and bring the single <div> to the top-level - and the documentation doesn't mention what happens if you attempt to copy (or paste) "HTML" like that - though I assume Windows doens't care and just treats it as a big string, but the possibility of having fun with other applications that consume pasted HTML (eg Word, Excel, etc) because this is how security vulnerabilities start.虽然像<span><div></div></span>这样的 HTML 在语法上有效且格式正确,但 HTML 本身不允许<span>成为<div>的父级,并要求浏览器分解外部<span>分成不同的兄弟姐妹和堂兄弟,并将单个<div>带到顶层 - 并且文档没有提到如果你尝试复制(或粘贴)“HTML”会发生什么 - 尽管我认为Windows 确实如此t 关心并且只是将其视为一个大字符串,但是可以与其他使用粘贴的HTML的应用程序(例如 Word、Excel 等)一起玩,因为这就是安全漏洞的开始方式。
    • Also, it's also completeley undocumented how Windows and other applications handle HTML's Custom Elements feature.此外,Windows 和其他应用程序如何处理 HTML 的自定义元素功能也完全没有记录。
  • Then you need to generate a header, with the right parameters, and the right formatting just for it to work .然后,您需要生成一个 header,具有正确的参数和正确的格式,以使其正常工作 Computers are awful.电脑太可怕了。

  • As you're passing in a single large element (the <table> , I assume?) then the <table> 's outerHTML can be the bounds of the actual HTML fragment that will (or rather, should ) be copied by the receiving application.当您传入单个大元素( <table> ,我假设?)时, <table>outerHTML可以是实际 HTML 片段的边界,该片段将(或者更确切地说,应该)由接收方复制应用。

    • This outer element, the fragment, is marked with HTML comments <!--StartFragment--> and <!--EndFragment--> .这个外部元素,片段,用 HTML 注释<!--StartFragment--><!--EndFragment-->
  • Only now can you calculate the values of those header parameters (which also represent an intentionally redundant representation of the <!--Start/EndFragment--> bounds)...只有现在您才能计算那些 header 参数的值(它们代表<!--Start/EndFragment-->边界的有意冗余表示)...

    • ... the problem is the insertion of those Start/EndFragment comments into the HTML makes the message longer would break any previously calculated absolute offsets. ...问题是将这些Start/EndFragment注释插入 HTML 会使消息更长会破坏任何先前计算的绝对偏移量。

So, (Doug DeMuro voice) this is the template for text data representing a HTML fragment being placed into the Windows Clipboard:因此, (Doug DeMuro 语音)是文本数据的模板,该模板代表 HTML 片段被放入 Windows 剪贴板:

Version:1.0
StartHTML:AAAA
EndHTML:BBBB
StartFragment:CCCC
EndFragment:DDDD
[StartSelection:CCCC
EndSelection:CCCC]
<HTML goes here>
  • The headers are separated by simple line-breaks.标题由简单的换行符分隔。 Curiously MS's documentation says that all 3 major line-break-styles were permissable ( \r , \r\n , and \n ),奇怪的是 MS 的文档说所有 3 种主要的换行样式都是允许的( \r\r\n\n ),

  • The last 2 headers/parameters ( StartSelection and EndSelection ) are optional ( but such that you must either supply neither or supply both - supplying only one of the two Start/EndSelection parameter will break things in unspecified ways.最后 2 个标头/参数( StartSelectionEndSelection )是可选的(但是您必须既不提供也不能提供两者 - 仅提供两个Start/EndSelection参数之一会以未指定的方式破坏事情。

  • Now do this:现在这样做:

    1. Copy that template into a new String and stick your completed HTML directly at the end of the header, separated by a single line-break.将该模板复制到一个新String中,并将完成的 HTML 直接粘贴在 header 的末尾,用一个换行符分隔。
    2. Take a look at that header above.看看上面那个header。 See at the top where it says Version:1.0 ?在顶部看到Version:1.0吗? Yeah?是的? Good.好的。 Ignore it.忽略它。
    3. Now see th StartHTML parameter below.现在请参阅下面的StartHTML参数。 We will calculate that last.我们将最后计算。 Ignore it for now暂时忽略它
    4. Next is EndHTML , which is the absolute byte offset (from the start of the header, not the HTML) of the end of the HTML text itself - basically it's the message length .接下来是EndHTML ,它是 HTML 文本本身结尾的绝对字节偏移量(从 header 的开头,而不是 HTML) - 基本上是消息长度
    5. StartFragment is the absolute byte offset (from the start of the header) to the < in a well-formed HTML element representing the fragment itself. StartFragment是表示片段本身的格式良好的 HTML 元素中的绝对字节偏移量(从标头的开头)到<
    • The inserted <!--Start/EndFragment--> comments must be considered outside the fragment (ie a String representation of your fragment's raw HTML would not have those comments in it anywhere)..插入的<!--Start/EndFragment-->注释必须被考虑在片段之外(即片段的原始 HTML 的String表示不会在任何地方包含这些注释)..
    1. EndFragment is the absolute byte offset (from the start of the header) to the end of the fragment. EndFragment是绝对字节偏移量(从标头的开头)到片段的结尾。 This is an exclusive upper-bound (so if StartFragment=100 and EndFragment=150 then the fragment is 50 char in length, simple).这是一个排他的上限(所以如果StartFragment=100EndFragment=150则片段长度为 50 个字符,简单)。
      • Important note: Remember the text run represented by Start/EndFragment must be a valid kinda-"self-contained" element.重要提示:请记住,由Start/EndFragment表示的文本运行必须是有效的有点“自包含”的元素。 So you cannot have a fragment that abrubtly ends inside a tag or its attributes - nor start half-way through a container element's many text nodes...所以你不能有一个在标签或其属性突然结束的片段 - 也不能从容器元素的许多文本节点中途开始......
      • ... however the Start/EndSelection headers, if present, can start and end at arbitrary points in the human-readable text (but conversely, the documentation does not say what happens if Start/EndSelection are inside an element's tags or attributes, for example). ...但是,如果Start/EndSelection标头存在,则可以在人类可读文本中的任意点开始和结束(但相反,文档没有说明如果Start/EndSelection在元素的标签或属性内会发生什么,例如例子)。
  • Then substitute those calculated numbers into those BBBB / CCCC /etc placeholders below: but do not delete unused placeholders : instead replace them with a leading digit '0' character.然后将这些计算的数字替换为下面的那些BBBB / CCCC /etc 占位符:但不要删除未使用的占位符:而是用前导数字'0'字符替换它们。

    • Don't worry: in this case (at least) any leading zeroes are not interpreted as forcing octal (base-8) integer parsing, phew .别担心:在这种情况下(至少)任何前导零都不会被解释为强制八进制(base-8) integer 解析,
  1. Oh, almost forgot : go back to the top to caclulate StartHTML , which is the absaolute byte offset to the start of the HTML text (and of the opening '<' in <htm> I assume).哦,差点忘了: go 回到顶部以计算StartHTML ,这是 HTML 文本开头的绝对字节偏移量(以及我假设<htm>中的开头'<' )。

So you'll end up with this:所以你最终会得到这个:

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>";

and you just need to pass it into SetText ( not SetData ) with TextDataFormat.Html :你只需要将它传递给SetText不是SetData )与TextDataFormat.Html

Clipboard.SetText( htmlInTheClipboardLooksLikeThis, TextDataFormat.Html );

and just running that in Linqpad gives us something we can paste directly into Word... and it indeed imported it as a Word table:只需在 Linqpad 中运行它,我们就可以直接粘贴到 Word 中……它确实将其导入为 Word 表格:

在此处输入图像描述

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

相关问题 清理从 MS Word 粘贴的内容 - cleaning up content pasted from MS Word 如何使用c#Word Interop清除MS Office剪贴板 - How to clear the MS Office Clipboard using c# Word Interop 如何以编程方式水平移动MS Word表 - How to move a MS Word table horizontally programmatically 如何使用 Microsoft Office Word Interop 与复制+粘贴的表格进行交互? 粘贴的表格不会添加到 document.Tables.count - How can you interact with a copied+pasted Table using Microsoft Office Word Interop? Pasted table doesn't add to document.Tables.count 使用 C# 创建 MS Word 动态表 - Create MS Word Dynamic Table using C# 如何在.net中创建类似String类的密封类,以便我们可以在不创建类似字符串str =“abc”的实例的情况下分配值 - How to create sealed class like String class in .net so that we can assign value without creating instance like string str=“abc” 如何将单词字段复制到剪贴板 - How to copy word field to clipboard 在 selenium 按钮单击 C# 中的变量后,如何分配复制到剪贴板的字符串? - How can I assign string copied to clipboard after selenium button click to a variable in C#? 如何通过使用C#中的书签获取MS Word中表的引用 - How to get the reference of a table in MS Word by using bookmark in C# 如何使用C#在没有循环的情况下将矩阵复制到Word表中 - How to Copy a matrix into Ms Word Table without loop with C#
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM