2010-07-22 67 views
6

Tôi đang gặp sự cố khi tìm kiếm biểu mẫu này.C# Mở Định dạng Bảng tính Xml SDK 2.0 Định dạng Ngày giờ Di động

tình hình của tôi:

  • SDK 2.0
  • không mẫu bảng
  • C# 4.0 trong VS2010

vấn đề của tôi:
Một số dữ liệu trong file excel tôi muốn xây dựng tồn tại ở định dạng DateTime. Như tôi không wan't để sử dụng chỉ dây (chuỗi datetimes không thể được sắp xếp đúng) Tôi muốn thiết lập các tế bào có chứa DateTime để một định dạng của tôi lựa chọn như tôi sẽ làm trong excel.
Theo hiểu biết của tôi, tôi phải sử dụng Biểu định kiểu để đến thời điểm đó. Tôi đã duyệt web trong một thời gian để tìm một người có một lời giải thích đơn giản cho vấn đề này, nhưng có vẻ như rất khó tìm.

Tôi đã có bảng tính trong mem, với khả năng thêm dữ liệu, thông qua SheetData. điều duy nhất tôi thiếu là định dạng/kiểu dáng của các ô.

đây là cách xa tôi nhận:

DocumentFormat.OpenXml.Packaging.SpreadsheetDocument doc = SpreadsheetDocument.Create("test.xlsx", SpreadsheetDocumentType.Workbook); 

WorkbookPart wbPart = doc.AddWorkbookPart(); 
wbPart.Workbook = new Workbook(); 

SheetData data = new SheetData(
      new Row(...etc)); 

WorksheetPart wsPart = wbPart.AddNewPart<WorksheetPart>(); 
wsPart.Worksheet = new Worksheet(data); 

Sheets sheets = doc.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets()); 

Sheet sheet = new Sheet() { Id = doc.WorkbookPart.GetIdOfPart(wsPart), SheetId = 1, Name = "TestSheet" }; 
sheets.Append(sheet); 

wbPart.Workbook.Save(); 

doc.Close(); 

ở đâu và làm thế nào tôi có thể thêm bổ sung đơn giản để phong cách như thời gian ngày (ví dụ, "dd-MM-yyyy"), và phong cách có thể tiến bộ hơn sau này ?

Tôi hy vọng tôi là đủ :) cụ thể trong khi đó tôi sẽ tiếp tục tìm kiếm ...

THX !!!

+0

Bạn đã bao giờ làm việc này ra? –

+0

Bạn đã không đọc thông số kỹ thuật của Office Open XML chưa? Nó chỉ 6.000 trang ... :-) jk tất nhiên, tôi đang chiến đấu với các vấn đề tương tự "nhỏ" bản thân mình ngay bây giờ. –

+1

nope tôi không bao giờ làm, xin lỗi về điều đó ... chúng tôi quyết định sử dụng một công cụ của bên thứ ba mà làm cho các tờ :) –

Trả lời

3

Có rất nhiều tham gia vào định dạng số làm ngày.

Bạn cần bắt đầu với định dạng số. Xác định định dạng được tích hợp phù hợp với mẫu bạn muốn hoặc tạo mẫu tùy chỉnh. Các định dạng dựng sẵn nằm trong ECMA-376, Ấn bản thứ hai, Phần 1 - Nguyên tắc cơ bản và tham chiếu ngôn ngữ đánh dấusection 18.8.30 (tham chiếu cho kiểu và <numFmt>. Nếu bạn cần tạo định dạng tùy chỉnh, hãy bắt đầu bằng ID 164 và thêm chúng vào . các yếu tố <numFmts> trong tập tin styles.xml bạn này có thể truy cập trong SDK như:

doc.WorkbookPart.WorkbookStylesPart.Stylesheet.NumberingFormats 

Tiếp theo, bạn cần phải có một định dạng ô đó đề cập đến một dạng ngày bạn luôn cần một định dạng tế bào, không có built-. Kiểu dáng di động đề cập đến định dạng số bằng numFmtId và được xác định trong phạm vi styles.xml bên trong <cellXfs>. Điều này có thể truy cập được trong sdk là:

doc.WorkbookPart.WorkbookStylesPart.Stylesheet.CellStyles 

Bản thân kiểu ô không có ID. Chúng được gọi bằng vị trí zero-index trong danh sách kiểu ô. Vì vậy, khi bạn tạo các ô, hãy đặt chỉ mục kiểu của chúng thành kiểu bạn muốn cho ngày của bạn.

Đối với giá trị, bạn có thể lưu trữ chúng ở định dạng ISO 8601 nhưng Excel 2010 vẫn sử dụng định dạng ngày tháng để lưu trữ ngày của nó. Nếu bạn sử dụng bất kỳ thứ gì khác ngoài ngày nối tiếp dựa trên 1900, bạn cần chỉ định nó trong các thuộc tính sổ làm việc.

doc.WorkbookPart.Workbook.WorkbookProperties.DateCompatibility 

Có hai khả năng tương thích các thiết lập ngày để lưu trữ các giá trị nối tiếp ngày, họ có thể là cơ sở 1900 hoặc cơ sở năm 1904. 1900 là gì Excel 2010 sử dụng và 1904 là để tương thích ngược với cũ Excel cho Mac.

Trong số serial ngày dựa trên 1900, số là ngày kể từ ngày 31 tháng 12 năm 1899 với biến chứng thêm mà bạn phải coi là ngày 29 tháng 2 năm 1900 là ngày hợp lệ mặc dù 1900 về mặt kỹ thuật không phải là năm nhuận.

Dưới đây là phương pháp tôi đã viết để chuyển đổi từ các giá trị nối tiếp ngày thành DateTime. Bạn cần ngược lại.

/// <summary> 
/// Represents the formula used for converting date serial values stored within the workbook into DateTime instances. 
/// </summary> 
/// <remarks> 
/// Information on date serial conversion is available here: http://www.documentinteropinitiative.com/implnotes/ISO-IEC29500-2008/001.018.017.004.001.000.000.aspx 
/// </remarks> 
public enum XlsxDateCompatibility 
{ 
    /// <summary> 
    /// Standard dates are based on December 30, 1899 and are considered "Standard 1900" dates. 
    /// </summary> 
    StandardBase1900, 

    /// <summary> 
    /// Excel for Windows backwards compatible dates are based on December 31, 1899 are are considered "Backwards compatible 1900" dates. 
    /// </summary> 
    BackwardsCompatibleBase1900, 

    /// <summary> 
    /// Excel for Macintos backwards compatible dates are based on January 1, 1904 and are considered "1904" dates. 
    /// </summary> 
    BackwardsCompatibleBase1904 
} 

    private static readonly IDictionary<XlsxDateCompatibility, DateTime> _dateSerialBaseDates 
     = new Dictionary<XlsxDateCompatibility, DateTime> 
      { 
       {XlsxDateCompatibility.StandardBase1900, new DateTime(1899, 12, 30)}, 
       {XlsxDateCompatibility.BackwardsCompatibleBase1900, new DateTime(1899, 12, 31)}, 
       {XlsxDateCompatibility.BackwardsCompatibleBase1904, new DateTime(1904, 1, 1)} 
      }; 

    public static DateTime DateSerialToDateTime(double dateSerial, XlsxDateCompatibility dateCompatibility) 
    { 

     // special case for dateCompaitility 1900, Excel thinks 1900 is a leap year 
     // http://support.microsoft.com/kb/214019 
     if (dateCompatibility == XlsxDateCompatibility.BackwardsCompatibleBase1900 && dateSerial >= 61.0) 
     { 
      dateSerial -= 1; 
     } 

     DateTime baseDate;   
     if (!_dateSerialBaseDates.TryGetValue(dateCompatibility, out baseDate)) 
     { 
      baseDate = _dateSerialBaseDates[XlsxDateCompatibility.StandardBase1900]; 
     } 
     return baseDate.AddDays(dateSerial); 
    } 
Các vấn đề liên quan