[英]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>
)。
<script><head></p>
. <script><head></p>
这样的事情。<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 等)一起玩,因为这就是安全漏洞的开始方式。 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 片段的边界,该片段将(或者更确切地说,应该)由接收方复制应用。
<!--StartFragment-->
and <!--EndFragment-->
.<!--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-->
边界的有意冗余表示)...
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 个标头/参数(
StartSelection
和EndSelection
)是可选的(但是您必须既不提供也不能提供两者 - 仅提供两个Start/EndSelection
参数之一会以未指定的方式破坏事情。
Now do this:现在这样做:
String
and stick your completed HTML directly at the end of the header, separated by a single line-break.String
中,并将完成的 HTML 直接粘贴在 header 的末尾,用一个换行符分隔。Version:1.0
?Version:1.0
吗? Yeah?StartHTML
parameter below.StartHTML
参数。 We will calculate that last.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) - 基本上是消息长度。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 元素中的绝对字节偏移量(从标头的开头)到<
。<!--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
表示不会在任何地方包含这些注释)..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=100
和EndFragment=150
则片段长度为 50 个字符,简单)。
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...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'
字符替换它们。
StartHTML
, which is the absaolute byte offset to the start of the HTML text (and of the opening '<'
in <htm>
I assume).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.