Office Open XML SDK中是否有現有的API或第三方從SpreadsheetML/.xlsx文件中正確讀取日期?用於從SpreadsheetML文件中讀取日期的現有API?
由於當值爲日期時(numFmtId +自定義數字格式),會有很多變量影響檢測,然後將日期序列轉換爲DateTime值(標準,向後兼容和1904超級向後兼容工作簿),這似乎是合乎邏輯的,這是SDK將提供的東西,或者至少有人會有現有的代碼片段來處理。
我正在使用C#,但任何語言的解決方案將罰款。
Office Open XML SDK中是否有現有的API或第三方從SpreadsheetML/.xlsx文件中正確讀取日期?用於從SpreadsheetML文件中讀取日期的現有API?
由於當值爲日期時(numFmtId +自定義數字格式),會有很多變量影響檢測,然後將日期序列轉換爲DateTime值(標準,向後兼容和1904超級向後兼容工作簿),這似乎是合乎邏輯的,這是SDK將提供的東西,或者至少有人會有現有的代碼片段來處理。
我正在使用C#,但任何語言的解決方案將罰款。
看起來沒有任何東西已經專門用於此目的。這是我想出的例程。
/// <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);
}
我從來沒有讀過日期,但我想象你必須將你正在閱讀的單元格的樣式索引與x:numFmts
元素中的日期樣式索引進行比較,您可以在x:cellStyle
中找到它。我知道Office 2010在單元格上有一個日期數據類型指示符,因此如果您使用該版本,那麼<x:c t='d'>
就會更容易找到數據是否爲日期。這是它會是什麼樣子在Office 2010:
<x:c r="C4" t="d">
<x:v>1976-11-22T08:30Z</x:v>
</x:c>
將數據轉換成一個日期時間,我相信所有你需要做的就是一個DateTime.FromOADate(cellvalue)
其中cellValue是雙。我知道我們在將日期插入到我們的Excel文檔之前將DateTime轉換爲OADate,所以我想象使用FromOADate方法可以正常工作。
就任何API來做這些功能,我沒有意識到任何將執行你想要的,但我希望它將被包含在SDK的未來版本。
感謝您的意見。關於如何識別日期和技術細節,我已經提出了很好的答案。這實際上比你的回答顯示要複雜得多。我有足夠的信息來編寫自定義代碼來讀取日期,但我突然想到這應該是一個常見問題,並且很驚訝我找不到任何現有的代碼來處理它。 – 2011-01-20 04:14:46