本文转自:https://stackoverflow.com/questions/8614910/paste-from-excel-into-c-sharp-app-retaining-full-precision#

I have data in an Excel spreadsheet with values like this:

  • 0.69491375
  • 0.31220394

The cells are formatted as Percentage, and set to display two decimal places. So they appear in Excel as:

  • 69.49%
  • 31.22%

I have a C# program that parses this data off the Clipboard.

var dataObj = Clipboard.GetDataObject();
var format = DataFormats.CommaSeparatedValue; if (dataObj != null && dataObj.GetDataPresent(format))
{
var csvData = dataObj.GetData(format);
// do something
}

The problem is that csvData contains the display values from Excel, i.e. '69.49%' and '31.22%'. It does not contain the full precision of the extra decimal places.

I have tried using the various different DataFormats values, but the data only ever contains the display value from Excel, e.g.:

  • DataFormats.Dif
  • DataFormats.Rtf
  • DataFormats.UnicodeText
  • etc.

As a test, I installed LibreOffice Calc and copy/pasted the same cells from Excel into Calc. Calc retains the full precision of the raw data.

So clearly Excel puts this data somewhere that other programs can access. How can I access it from my C# application?

Edit - Next steps.

I've downloaded the LibreOffice Calc source code and will have a poke around to see if I can find out how they get the full context of the copied data from Excel.

I also did a GetFormats() call on the data object returned from the clipboard and got a list of 24 different data formats, some of which are not in the DataFormats enum. These include formats like Biff12Biff8Biff5Format129 among other formats that are unfamiliar to me, so I'll investigate these and respond if I make any discoveries...

 
 
 
 

Also not a complete answer either, but some further insights into the problem:

When you copy a single Excel cell then what will end up in the clipboard is a complete Excel workbook which contains a single spreadsheet which in turn contains a single cell:

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

Now, when you dump the content of the XElement to the console you can see that you indeed get a complete Excel Workbook. Also the "XML Spreadsheet" format contains the internal representation of the numbers stored in the cell. So I guess you could use Linq-To-Xml or similar to fetch the data you need:

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

I've also tried to read the Biff formats using the Excel Data Reader however the resulting DataSets always came out empty...

 
 

The BIFF formats are an open specification by Microsoft. (Note, that I say specification not standard). Give a read to this to get an idea of what is going on.

Then those BIFF you see correspond to the some Excel formats. BIFF5 is XLS from Excel 5.0 and 95, BIFF8 is XLS from Excel 97 to 2003, BIFF12 is XLSB from Excel 2003, note that Excel 2007 can also produce them (I guess Excel 2010 too). There is some documentation here and also here (From OpenOffice) that may help you make sense of the binary there...

Anyways, there is some work has been done in past to parse this documents in C++, Java, VB and for your taste in C#. For example this BIFF12 Reader, the project NExcel, and ExcelLibrary to cite a few.

In particular NExcel will let you pass an stream which you can create from the clipboard data and then query NExcel to get the data. If you are going to take the source code then I think ExcelLibrary is much more readable.

You can get the stream like this:

var dataobject = System.Windows.Forms.Clipboard.GetDataObject();
var stream = (System.IO.Stream)dataobject.GetData(format);

And read form the stream with NExcel would be something like this:

var wb = getWorkbook(stream);
var sheet = wb.Sheets[0];
var somedata = sheet.getCell(0, 0).Contents;

I guess the actual Office libraries from Microsoft would work too.

I know this is not the whole tale, please share how is it going. Will try it if I get a chance.

https://stackoverflow.com/questions/13647945/how-use-clipboard-to-move-data-from-net-application-to-excel?noredirect=1

When I copy from Excel, the clipboard holds 24 formats!

System.Windows.Clipboard.GetDataObject().GetFormats().Dump();
  • EnhancedMetafile
  • System.Drawing.Imaging.Metafile
  • MetaFilePict
  • Bitmap
  • System.Drawing.Bitmap
  • System.Windows.Media.Imaging.BitmapSource
  • Biff12
  • Biff8
  • Biff5
  • SymbolicLink
  • DataInterchangeFormat
  • XML Spreadsheet
  • HTML Format
  • Text
  • UnicodeText
  • System.String
  • CSV
  • Rich Text Format
  • Embed Source
  • Object Descriptor
  • Link Source
  • Link Source Descriptor
  • Link
  • Format129

https://stackoverflow.com/questions/42481912/copying-decimal-values-from-excel-to-c-sharp-causes-to-copy-only-displayed-value

Try this:

IDataObject dataObject = Clipboard.GetDataObject();
System.IO.MemoryStream stream = dataObject.GetData("XML Spreadsheet") as System.IO.MemoryStream;
if(stream != null)
{
stream.SetLength(stream.Length - 1);
XElement xml = XElement.Load(stream);
XNamespace ns = "urn:schemas-microsoft-com:office:spreadsheet"; double actualValue;
var data = xml.Descendants(ns + "Data").Where(x => (string)x.Attribute(ns + "Type") == "Number");
if(data != null && data.Any())
{
actualValue = (double)data.First();
MessageBox.Show(actualValue.ToString());
} stream.Dispose();
}

[转]Paste from Excel into C# app, retaining full precision的更多相关文章

  1. Word Excel 操作总结

    1.与office无关使用 Aspose.Cells.dll,Aspose.Words.dll 2.使用Microsoft.Office.Interop.Excel Microsoft.Office. ...

  2. asp.net利用剪切板导出excel

    public enum ClipboardFormats : uint { CF_TEXT = 1, CF_BITMAP = 2, CF_METAFILEPICT = 3, CF_SYLK = 4, ...

  3. 对.NET中导出数据到EXCEL的几种方法探讨

    最近在做一个报表系统的时候,需要把DATASET中的数据导到EXCEL当中,于是在网上找了一遍,发现了好几种方法,本来以为应该差不多,但后来经过一一试用后,发现在性能上真的差别很大,现在就介绍一下,同 ...

  4. 使用VBA将Excel指定单元格数据、字符串或者图表对象插入到Word模板指定书签处

    准备工作: 1.首先需要提供一个word模板,并且标记好您要插入书签的位置,定义书签的命名.如图 2.模拟您要插入的Excel原始数据和图表对象 插入代码如下: Private Sub Command ...

  5. c# 导出数据到Excel模板

    最近在做一个发邮件的功能,客户要求需要导出一个Excel附件,并给了附件的格式, eg: Last Name 姓 First Name 名 Chinese Characters汉字书写(仅大陆人填写) ...

  6. c#读取excel

    Provider根据实际EXCEL的版本来设置,推荐使用ACE接口来读取.需要Access database Engine. 注意修改注册表以下两项的值为0.否则导入EXCEL当单元格内字符长度超过2 ...

  7. C#操作Excel的技巧与方法 设置单元格等

    C#操作Excel可以分为客户端和插件版本,区别就是是否需要Excel环境,功能实现一样 一.通用操作与处理(有点乱有时间再整理) 1:工程对excel类库的导入,如: c:\program file ...

  8. c#excel的操作例子

    class MyData//存储行数据 { public List<string> RowData { get; set; } } static void Main(string[] ar ...

  9. 导出带图形的数据excel表

    public static string StatisticsSR(string parmStr) { try { StatisticsSRInfo parm = JsonConvert.Deseri ...

随机推荐

  1. Dc:7 Vulnhub Walkthrough

    靶机下载地址: https://www.vulnhub.com/entry/dc-7,356/ 主机扫描: http://10.10.202.161/ Google搜索下: SSH 登录 以上分析得出 ...

  2. MySQL密码正确却无法本地登录-1045 Access denied for user 'root'@'localhost' (using password:YES

    MySQL密码正确却无法本地登录 报错如下: ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password ...

  3. web中状态码301和302的区别

    web中状态码301和302的区别 总的区别就是:302重定向只是暂时的重定向,搜索引擎会抓取新的内容而保留旧的地址,因为服务器返回302,所以,搜索搜索引擎认为新的网址是暂时的.而301重定向是永久 ...

  4. 活久见: maven pom 竟然都会崩溃!

    问题是: 我的应用的pom 并没有任何报错,但是代码报错,而且编译不通过. 如下,我本地项目,从 spring-cloud-alibaba-dependencies 0.2.1.RELEASE 升级到 ...

  5. Toggle the WinForms Ribbon Interface 切换 WinForms 功能区界面

    In this lesson, you will learn how to enable/disable the Ribbon User Interface in your application. ...

  6. SQL实用技巧:如何判断一个值是否为数字的方法

    检测是不是数字型的数据, 两种方法 1. ISNUMERIC ( expression ) 2. PATINDEX ( ‘%pattern%‘ , expression ) 1. ISNUMERIC  ...

  7. [转]为何选择 Flink

    本文转自:https://www.ituring.com.cn/book/tupubarticle/23229 第 1 章 为何选择 Flink 人们对某件事的正确理解往往来自基于有效论据的结论.要获 ...

  8. 【好书推荐】《剑指Offer》之硬技能(编程题1~6)

    本文例子完整源码地址:https://github.com/yu-linfeng/BlogRepositories/tree/master/repositories/sword 前一篇<[好书推 ...

  9. mysql5.7中timestam默认值'0000-00-00 00:00:00'报错

    在mysql5.7中设置 timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'会报错: 解决办法: mysql> set sql_mode='NO_A ...

  10. E-factory

    E-factory为生成XML和HTML提供了一种简单而紧凑的语法 # coding:utf-8 from lxml.builder import E def CLASS(*args): # clas ...