2011-12-23 26 views
7

Tôi có dữ liệu trong một bảng tính Excel với các giá trị như thế này:Dán từ Excel vào C# ứng dụng, duy trì độ chính xác đầy đủ

  • 0,69491375
  • 0,31220394

Các tế bào được định dạng như Tỷ lệ phần trăm, và đặt để hiển thị hai chữ số thập phân. Vì vậy, chúng xuất hiện trong Excel như:

  • 69,49%
  • 31.22%

tôi có một chương trình C# mà phân tích dữ liệu này ra khỏi Clipboard.

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

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

Vấn đề là csvData chứa các giá trị hiển thị từ Excel, ví dụ: '69 .49% 'và '31 0,22%'. Nó không chứa độ chính xác đầy đủ của các chữ số thập phân thêm.

Tôi đã thử bằng cách sử dụng khác nhau DataFormats giá trị khác nhau, nhưng dữ liệu duy nhất chứa các giá trị hiển thị từ Excel, ví dụ:

  • DataFormats.Dif
  • DataFormats.Rtf
  • DataFormats.UnicodeText
  • , vv

Khi thử nghiệm, tôi đã cài đặt LibreOffice C alc và sao chép/dán các ô tương tự từ Excel vào Calc. Calc giữ lại độ chính xác đầy đủ của dữ liệu thô.

Vì vậy, Excel rõ ràng đặt dữ liệu này ở đâu đó mà các chương trình khác có thể truy cập. Làm thế nào tôi có thể truy cập nó từ ứng dụng C# của tôi?

Chỉnh sửa - Các bước tiếp theo.

Tôi đã tải xuống mã nguồn của LibreOffice Calc và sẽ tìm hiểu xem tôi có thể tìm hiểu cách chúng có được ngữ cảnh đầy đủ của dữ liệu được sao chép từ Excel hay không.

Tôi cũng đã thực hiện cuộc gọi GetFormats() trên đối tượng dữ liệu được trả lại từ khay nhớ tạm và có danh sách 24 định dạng dữ liệu khác nhau, một số trong số đó không nằm trong en2 DataFormats. Chúng bao gồm các định dạng như Biff12, Biff8, Biff5, Format129 giữa các định dạng khác mà không quen với tôi, vì vậy tôi sẽ điều tra những điều này và trả lời nếu tôi thực hiện bất kỳ khám phá ...

+0

Tôi vừa thử dán dữ liệu trong 10 chương trình khác nhau và tất cả đều cho tôi dữ liệu được định dạng "69.00% \ r \ n" giống như tôi thấy nó Clipboard.GetData –

+0

Vâng, bạn nói đúng. Tôi đã suy nghĩ, Excel có clipboard bên trong riêng của nó, nơi nó lưu trữ tất cả các định dạng và dữ liệu chính xác, mà không được đưa vào clipboard chung? Và liệu Calc có một số hook vào clipboard trong Excel, rằng hầu hết các ứng dụng sẽ không có và không dễ dàng nhận được? Tôi sợ câu trả lời cho điều này. :-) – Lyall

+1

nếu Calc sử dụng móc excel, tôi không thể thấy lý do tại sao bạn không thể sử dụng cùng móc đó ... – Adam

Trả lời

6

Cũng không phải là một câu trả lời hoàn chỉnh một trong hai, nhưng một số hiểu biết sâu hơn vào các vấn đề:

Khi bạn sao chép một tế bào Excel đơn sau đó điều gì sẽ kết thúc trong clipboard là một bảng tính Excel hoàn chỉnh, trong đó có một bảng duy nhất mà trong lần lượt chứa một ô đơn lẻ:

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

Bây giờ, khi bạn đổ nội dung của XElement lên bàn điều khiển, bạn có thể thấy rằng bạn thực sự có được một sổ làm việc Excel hoàn chỉnh. Ngoài ra, định dạng "Bảng tính XML" chứa biểu diễn nội bộ của các số được lưu trữ trong ô. Vì vậy, tôi đoán bạn có thể sử dụng LINQ-To-Xml hoặc tương tự để lấy dữ liệu bạn cần:

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

Tôi cũng đã cố gắng để đọc các định dạng Biff sử dụng Excel Data Reader tuy nhiên DataSets kết quả luôn luôn xuất hiện trống rỗng ..

+0

Tôi đã kết thúc bằng cách sử dụng phương pháp này, cảm ơn vì sự thấu hiểu. Thú vị là các DataFormats enum không chứa "XML Spreadsheet" nhưng nó hoạt động khá độc đáo với một chút phân tích cú pháp của XML. – Lyall

3

Các định dạng BIFF là một đặc điểm kỹ thuật mở bởi Microsoft. (Lưu ý, rằng tôi nói đặc điểm kỹ thuật không tiêu chuẩn). Hãy đọc cho this để có ý tưởng về những gì đang diễn ra.

Sau đó, những BIFF bạn thấy tương ứng với một số định dạng Excel. BIFF5 là XLS từ Excel 5.0 và 95, BIFF8 là XLS từ Excel 97 đến 2003, BIFF12 là XLSB từ Excel 2003, lưu ý rằng Excel 2007 cũng có thể tạo chúng (tôi cũng đoán Excel 2010). Có một số tài liệu hướng dẫn here và cũng có thể here (Từ OpenOffice) có thể giúp bạn hiểu được nhị phân ở đó ...

Dù sao, có một số công việc đã được thực hiện trong quá khứ để phân tích các tài liệu này bằng C++, Java, VB và cho hương vị của bạn trong C#. Ví dụ: BIFF12 Reader, dự án NExcelExcelLibrary để trích dẫn một số ít.

Đặc biệt, NExcel sẽ cho phép bạn truyền một luồng mà bạn có thể tạo từ dữ liệu clipboard và sau đó truy vấn NExcel để lấy dữ liệu. Nếu bạn đang đi để lấy mã nguồn sau đó tôi nghĩ rằng ExcelLibrary là dễ đọc hơn nhiều.

Bạn có thể lấy dòng như thế này:

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

Và đọc hình thành dòng với NExcel sẽ là một cái gì đó như thế này:

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

Tôi đoán các thư viện văn phòng thực tế từ Microsoft sẽ làm việc quá .

Tôi biết đây không phải là toàn bộ câu chuyện, vui lòng chia sẻ cách thực hiện. Sẽ thử nếu tôi có cơ hội.

Các vấn đề liên quan