[转]Paste from Excel into C# 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 Biff12
, Biff8
, Biff5
, Format129
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.
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
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的更多相关文章
- Word Excel 操作总结
1.与office无关使用 Aspose.Cells.dll,Aspose.Words.dll 2.使用Microsoft.Office.Interop.Excel Microsoft.Office. ...
- asp.net利用剪切板导出excel
public enum ClipboardFormats : uint { CF_TEXT = 1, CF_BITMAP = 2, CF_METAFILEPICT = 3, CF_SYLK = 4, ...
- 对.NET中导出数据到EXCEL的几种方法探讨
最近在做一个报表系统的时候,需要把DATASET中的数据导到EXCEL当中,于是在网上找了一遍,发现了好几种方法,本来以为应该差不多,但后来经过一一试用后,发现在性能上真的差别很大,现在就介绍一下,同 ...
- 使用VBA将Excel指定单元格数据、字符串或者图表对象插入到Word模板指定书签处
准备工作: 1.首先需要提供一个word模板,并且标记好您要插入书签的位置,定义书签的命名.如图 2.模拟您要插入的Excel原始数据和图表对象 插入代码如下: Private Sub Command ...
- c# 导出数据到Excel模板
最近在做一个发邮件的功能,客户要求需要导出一个Excel附件,并给了附件的格式, eg: Last Name 姓 First Name 名 Chinese Characters汉字书写(仅大陆人填写) ...
- c#读取excel
Provider根据实际EXCEL的版本来设置,推荐使用ACE接口来读取.需要Access database Engine. 注意修改注册表以下两项的值为0.否则导入EXCEL当单元格内字符长度超过2 ...
- C#操作Excel的技巧与方法 设置单元格等
C#操作Excel可以分为客户端和插件版本,区别就是是否需要Excel环境,功能实现一样 一.通用操作与处理(有点乱有时间再整理) 1:工程对excel类库的导入,如: c:\program file ...
- c#excel的操作例子
class MyData//存储行数据 { public List<string> RowData { get; set; } } static void Main(string[] ar ...
- 导出带图形的数据excel表
public static string StatisticsSR(string parmStr) { try { StatisticsSRInfo parm = JsonConvert.Deseri ...
随机推荐
- abp示例项目BookStore搭建部署
之前部署过BookStore项目,但是换了新电脑也想好好学习下这个示例项目,于是在新电脑上重新拉了Git上的ABP项目代码,一编译生成BookStore项目就报错,可以参考 abp示例项目BookSt ...
- Java并发的若干基本陷阱、原理及解决方案
勿止于结论:持续探索与求证. 概述 为什么要使用并发 ? 有三点足够信服的理由: 性能提升.单核 CPU 的性能基本抵达瓶颈,充分挖掘多核 CPU 的能力,使得性能提升变成水平可扩展的. 事件本质.世 ...
- [Codeforces 1244C] The Football Season
思维加枚举 题意 :足球赛,赢平所得到的分数分别为w和d,w>d,分别求赢平输的场数,输出一组即可,即x+y+z=n 且 xw+yd=p的一组解. 可以扩展公约数做,但由于注意到d和w<1 ...
- 洛谷P5364 [SNOI2017]礼物 题解
传送门 /* 热情好客的小猴子请森林中的朋友们吃饭,他的朋友被编号为 1∼N,每个到来的朋友都会带给他一些礼物:大香蕉.其中,第一个朋友会带给他 11 个大香蕉,之后,每一个朋友到来以后,都会带给他之 ...
- gradle环境搭建
最近我在尝试了解跨平台技术的发展,首先则是想到了cordova.环境配置过程中有依赖gradle,下面简单记录了在windos10系统下搭建gradle环境的过程. 什么是gradle Gradle是 ...
- nltk的安装和简单使用
使用python进行自然语言处理,有一些第三方库供大家使用: ·NLTK(Python自然语言工具包)用于诸如标记化.词形还原.词干化.解析.POS标注等任务.该库具有几乎所有NLP任务的工具. ·S ...
- vue-router精简demo
cnpm install vue-router --save-dev 或者 cnpm install vue-router --save 全局引用VueRouter import VueRouter ...
- Flutter学习笔记(26)--返回拦截WillPopScope,实现1秒内点击两次返回按钮退出程序
如需转载,请注明出处:Flutter学习笔记(26)--返回拦截WillPopScope,实现1秒内点击两次返回按钮退出程序 在实际开发中,为了防止用户误触返回按钮导致程序退出,通常会设置为在1秒内连 ...
- iOS---------金额转大写
-(NSString *)digitUppercase:(NSString *)numstr{ double numberals=[numstr doubleValue]; NSArray *numb ...
- Linux下安装及使用mysql
(注:本人在centos7进行的安装及使用) 1.安装wget yum install wget 2.下载mysql安装包 wget http://repo.mysql.com/mysql57-com ...