从Excel粘贴到C#app,保持完全精确

Lya*_*all 7 c# excel paste

我在Excel电子表格中有数据,其值如下:

  • 0.69491375
  • 0.31220394

单元格格式为百分比,并设置为显示两个小数位.因此它们在Excel中显示为:

  • 69.49%
  • 31.22%

我有一个C#程序解析了这些数据Clipboard.

var dataObj = Clipboard.GetDataObject();
var format = DataFormats.CommaSeparatedValue;

if (dataObj != null && dataObj.GetDataPresent(format))
{
    var csvData = dataObj.GetData(format);
    // do something
}
Run Code Online (Sandbox Code Playgroud)

问题是csvData包含Excel的显示值,即'69 .49%'和'31 .22%'.它不包含额外小数位的完整精度.

我尝试过使用各种不同的DataFormats值,但数据只包含Excel的显示值,例如:

  • DataFormats.Dif
  • DataFormats.Rtf
  • DataFormats.UnicodeText
  • 等等

作为测试,我安装了LibreOffice Calc并将相同的单元格从Excel复制/粘贴到Calc中.Calc保留原始数据的完整精度.

很明显,Excel会将此数据放在其他程序可以访问的位置.如何从我的C#应用​​程序访问它?

编辑 - 后续步骤.

我已经下载了LibreOffice Calc源代码,并且会有一个问题,看看我是否能够从Excel中获取复制数据的完整上下文.

我还GetFormats()调用了从剪贴板返回的数据对象,并获得了24种不同数据格式的列表,其中一些不在DataFormats枚举中.这些措施包括格式,如Biff12,Biff8,Biff5,Format129其他格式不熟悉我之间,所以我会调查这些和回应,如果我做任何的发现...

afr*_*hke 6

也不是一个完整的答案,但对问题的一些进一步的见解:

当您复制单个Excel单元格时,最终会出现在剪贴板中的是一个完整的Excel工作簿,其中包含一个电子表格,该电子表格又包含一个单元格:

var dataObject = Clipboard.GetDataObject();
var mstream = (MemoryStream)dataObject.GetData("XML Spreadsheet");

// Note: For some reason we need to ignore the last byte otherwise
// an exception will occur...
mstream.SetLength(mstream.Length - 1);

var xml = XElement.Load(mstream);
Run Code Online (Sandbox Code Playgroud)

现在,当您将XElement的内容转储到控制台时,您可以看到您确实获得了一个完整的Excel工作簿."XML电子表格"格式还包含存储在单元格中的数字的内部表示.所以我想你可以使用Linq-To-Xml或类似方法来获取你需要的数据:

XNamespace ssNs = "urn:schemas-microsoft-com:office:spreadsheet";

var numbers = xml.Descendants(ssNs + "Data").
              Where(e => (string)e.Attribute(ssNs + "Type") == "Number").
              Select(e => (double)e);
Run Code Online (Sandbox Code Playgroud)

我也尝试使用Excel数据读取器读取Biff格式,但生成的DataSet总是空出来的......