在C#中,我需要将数据网格行复制到excel。由于连续中的某些值是双精度数,因此可以使用“-Infinity
”值。
我尝试将行复制为DataFormats.UnicodeText
或DataFormats.Text
,但这给了我输出“#NAME?
”,我应该看到“-Infinity
”(因为excel由于标准单元格格式,在“=
”中的减号之前自动插入“-Infinity
”。
在粘贴之前将单元格格式设置为“Text
”时,Excel不会在“=
”之前自动插入“-Infinity
”。顺便说一下,我不需要用excel中的double值进行任何计算,所以文本格式对我来说没问题。
所以我的问题是如何将数据复制到剪贴板并将其粘贴到Excel中,同时将单元格格式设置为“text”。
答案 0 :(得分:8)
从Raw Clipboard查看器开始,您可以看到复制
到剪贴板导致Excel向剪贴板抛出大量不同的格式。
其中大多数没有帮助,但其中一些是excel内部的,这意味着它(几乎)将保证数据与复制的数据相同。如果我是你,我可能会以 XML SpreadSheet 为目标,或者你感觉勇敢 Biff12 ,这也是xml(但是压缩)。与普通文本相比,这将使您可以更好地控制粘贴。
作为示例,上面的剪辑导致
<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<Styles>
<Style ss:ID="Default" ss:Name="Normal">
<Alignment ss:Vertical="Bottom"/>
<Borders/>
<Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="11" ss:Color="#000000"/>
<Interior/>
<NumberFormat/>
<Protection/>
</Style>
<Style ss:ID="s63">
<NumberFormat ss:Format="@"/>
</Style>
</Styles>
<Worksheet ss:Name="Sheet1">
<Table ss:ExpandedColumnCount="2" ss:ExpandedRowCount="2"
ss:DefaultRowHeight="15">
<Row>
<Cell><Data ss:Type="Number">1</Data></Cell>
<Cell><Data ss:Type="Number">2</Data></Cell>
</Row>
<Row>
<Cell><Data ss:Type="String">Test</Data></Cell>
<Cell ss:StyleID="s63"><Data ss:Type="String" x:Ticked="1">-Infinity</Data></Cell>
</Row>
</Table>
</Worksheet>
</Workbook>
所以看得更深一点......当我尝试使用Clipboard.SetData
将xml写入剪贴板时,看起来.Net剪贴板类做了一些奇怪而不是那么美妙的事情
剪贴板以一堆箔条开始。这当然导致Excel拒绝剪贴板内容。
为了解决这个问题,我使用Windows API(user32)调用来处理剪贴板
[DllImport("user32.dll", SetLastError = true)]
static extern uint RegisterClipboardFormat(string lpszFormat);
[DllImport("user32.dll")]
static extern IntPtr SetClipboardData(uint uFormat, IntPtr hMem);
[DllImport("user32.dll", SetLastError = true)]
static extern bool CloseClipboard();
[DllImport("user32.dll", SetLastError = true)]
static extern bool OpenClipboard(IntPtr hWndNewOwner);
private static void XMLSpreadSheetToClipboard(String S)
{
var HGlob = Marshal.StringToHGlobalAnsi(S);
uint Format = RegisterClipboardFormat("XML SpreadSheet");
OpenClipboard(IntPtr.Zero);
SetClipboardData(Format, HGlob);
CloseClipboard();
Marshal.FreeHGlobal(HGlob);
}
答案 1 :(得分:1)
感谢您的信息。经过一些搜索,我发现你可以使用.Net剪贴板类,但你不能将String传递给SetData()。这对我有用:
System::Text::UTF8Encoding^ enc = gcnew System::Text::UTF8Encoding();
System::Windows::Forms::Clipboard::SetData("XML Spreadsheet", gcnew MemoryStream(enc->GetBytes(data)));
答案 2 :(得分:0)
win32 api解决方案不适用于我。我发生了随机崩溃。 以下代码也可以正常工作,也可以与Unicode字符一起使用。
var xml = File.ReadAllText(@"..\..\SampleData\Clipboard-Example3.xml");
var stream = new MemoryStream(Encoding.UTF8.GetBytes(xml));
var dataObject = new DataObject();
dataObject.SetData("XML SpreadSheet", stream);
Clipboard.Clear();
Clipboard.SetDataObject(dataObject);