2016-09-21 49 views
1

Excel單元格中添加日期這是我在做什麼:使用的OpenXML

CellFormat cellFormat = 
       new CellFormat() 
       { NumberFormatId = (UInt32Value)14U, 
        FontId = (UInt32Value)0U, 
        FillId = (UInt32Value)0U, 
        BorderId = (UInt32Value)0U, 
        FormatId = (UInt32Value)0U, 
        ApplyNumberFormat = true }; 

sd.WorkbookPart.WorkbookStylesPart.Stylesheet.CellFormats.AppendChild<CellFormat>(cellFormat); 

_dateStyleIndex = sd.WorkbookPart.WorkbookStylesPart.Stylesheet.CellFormats.Count() - 1; 

,然後某處後來在我的代碼

else if (type == DataTypes.DateTime) 
{     
    DateTime dateTime = DateTime.Parse(text); 
    double oaValue = dateTime.ToOADate(); 
    cell.CellValue = new CellValue(oaValue.ToString(CultureInfo.InvariantCulture)); 
    cell.DataType = new EnumValue<CellValues>(CellValues.Date); 
    cell.StyleIndex = Convert.ToUInt32(_dateStyleIndex);    
} 

然而,當我驗證所生成的Excel與文件打開XML SDK工具,我得到以下驗證錯誤:屬性't'具有無效值'd'。枚舉約束失敗。

我在這裏錯過了什麼?提前謝謝你的幫助。

PS:添加,這是x:sheetData的樣子。它給我驗證錯誤:

<x:sheetData xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main"> 
    <x:row r="2"> 
    <x:c r="B2" t="s"> 
     <x:v>0</x:v> 
    </x:c> 
    <x:c r="C2" t="s"> 
     <x:v>1</x:v> 
    </x:c> 
    <x:c r="D2" t="s"> 
     <x:v>2</x:v> 
    </x:c> 
    </x:row> 
    <x:row r="3"> 
    <x:c r="B3" t="s"> 
     <x:v>3</x:v> 
    </x:c> 
    <x:c r="C3" t="s"> 
     <x:v>6</x:v> 
    </x:c> 
    <x:c r="D3" s="1" t="d"> 
     <x:v>42634.906087963</x:v> 
    </x:c> 
    </x:row> 
    <x:row r="4"> 
    <x:c r="B4" t="s"> 
     <x:v>4</x:v> 
    </x:c> 
    <x:c r="C4" t="s"> 
     <x:v>7</x:v> 
    </x:c> 
    <x:c r="D4" s="1" t="d"> 
     <x:v>42634.9062037037</x:v> 
    </x:c> 
    </x:row> 
    <x:row r="5"> 
    <x:c r="B5" t="s"> 
     <x:v>5</x:v> 
    </x:c> 
    <x:c r="C5" t="s"> 
     <x:v>8</x:v> 
    </x:c> 
    <x:c r="D5" s="1" t="d"> 
     <x:v>42634.9062847222</x:v> 
    </x:c> 
    </x:row> 
</x:sheetData> 
+0

難道你不只是將cell.DataType設置爲CellValues.Date?我不相信你爲此實例化一個EnumValue。 DataType有一個屬性SchemaAttrAttribute,我假設它是空的是什麼導致錯誤。 – Dispersia

+0

而你沒有說它投擲的是什麼線,但是如果它在CellValue =上,試着將你的DataType設置在它之前。在設置其內容之前,可能需要知道它的類型。 – Dispersia

+0

是的,這是愚蠢的實例化一個EnumValue。 DataType的所有屬性都設置正確,但仍然出現此錯誤。 –

回答

6

爲了最廣泛的兼容性使用CellValues.Number作爲單元格數據類型。

根據docs,CellValues.Date適用於Excel 2010,因此您可能希望避免它與Excel 2007(及潛在的其他應用程序)完全向後兼容。

//broadly supported - earliest Excel numeric date 01/01/1900 
DateTime dateTime = DateTime.Parse(text); 
double oaValue = dateTime.ToOADate(); 
cell.CellValue = new CellValue(oaValue.ToString(CultureInfo.InvariantCulture)); 
cell.DataType = new EnumValue<CellValues>(CellValues.Number); 
cell.StyleIndex = Convert.ToUInt32(_numericDateCellFormatIndex); 


//supported in excel 2010 - not XLSX Transitional compliant 
DateTime dateTime = DateTime.Parse(text); 
cell.CellValue = new CellValue(dateTime.ToString("s")); 
cell.DataType = new EnumValue<CellValues>(CellValues.Date); 
cell.StyleIndex = Convert.ToUInt32(_sortableDateCellFormatIndex); 

earlier more complete answer表明,Excel 2010中默認情況下不使用「排序」 CellValues.Date數據類型本身。

推測CellValues.Date類型的原因是爲了克服數字日期的限制,例如最早的Excel數字日期是01/01/1900。

digitalpreservation.gov explains some of the historical intention behind the date cell type,並且此頁面說明了XLSX Transitional is the version used by mainstream real world applications(2014年測試)。

XLSX Strict has a value type for cells of date, using the Complete, Extended Format Calendar representations in ISO 8601. For reasons of backwards compatibility, this typed use of ISO 8601 dates is not permitted in XLSX Transitional.

Late in the ISO standardization process for OOXML, a proposal was made to adopt the ISO 8601 format for dates and times in spreadsheets.

The experts present at the ISO 29500 Ballot Resolution Meeting where votes were held on the outstanding proposals for the OOXML format were primarily experts in XML and in textual documents rather than with spreadsheets

Since the intent of the Transitional variant of ISO 29500 was to be compatible with the existing corpus of .xlsx documents and the applications designed to handle them, an amendment to Part 4 to disallow ISO 8601 dates in the Transitional variant was introduced. Secondly, ISO 8601 is a very flexible format, and any use in a context that aims at interoperability needs to be specific about which particular textual string patterns are expected for dates and times.

... Tests in November 2014 indicated that Google Sheets and Libre Office both created new documents in the Transitional variant

+0

謝謝,它現在可以工作。但我不明白爲什麼CellValues應該是數字而不是Date。那麼Date的用法是什麼? –

+1

'CellValues.Date'沒有廣泛的支持(答案更新)。 –

+2

因爲我在ISO8601中共同編寫了日期支持,並且在該圖書館的國會文件上工作,所以有趣的是遇到了這個問題。添加了d屬性是爲了安撫涉及標準化過程的幾個人,他們不喜歡日期被存儲爲電子表格中「自1900年1月1日以來的天數」這一事實,並希望通過更改規格來改變日期。這可能是一個不錯的主意,但從Lotus 1-2-3開始就是這樣。正如克里斯說的那樣,您應該使用CellValues,並將日期存儲爲自1900年1月1日以來的幾天。 –