34

セルの 1 つの xlsx ファイルに「2011 年 4 月 5 日」(月/日/年) の形式の日付があります。ファイルを解析し、それらのデータをいくつかのクラスにロードしようとしています。

これまでのところ、セルを解析する部分は次のようになります。

string cellValue = cell.InnerText;
if (cell.DataType != null)
{
    switch (cell.DataType.Value)
    {
        case CellValues.SharedString:
            // get string from shared string table
            cellValue = this.GetStringFromSharedStringTable(int.Parse(cellValue));
            break;
    }
}

日付が cell.DataType であることを望みました。実際には、日付が「2011 年 4 月 5 日」のセルを解析すると、cell.DataType の値は null で、セルの値は「40638」であり、共有文字列テーブルへのインデックスではありません。(私は以前にそれを試しましたが、例外が発生しました。)

何か案は?ありがとう

4

8 に答える 8

43

Open XML stores dates as the number of days from 1 Jan 1900. Well, skipping the incorrect 29 Feb 1900 as a valid day. You should be able to find out algorithms to help you calculate the correct value. I believe some developers use DateTime.FromOADate() as a helper.

Also, the Cell class has the DataType property as Number by default. So if it's null, it's a number, which includes dates in our case.

You only go to the shared strings table when the date stored is before the epoch (1 Jan 1900 in this case). And then in that case, the CellValue of the Cell class holds the index to the shared string table.

于 2012-11-01T13:23:49.493 に答える
2

私は同じ問題を抱えていました-EPPlus http://epplus.codeplex.com/に切り替えました

LGPL ライセンスがあることに注意してください。したがって、コード ベースを GPL の問題から保護する必要がある場合は、ライブラリをそのまま使用するだけで、元のコード ベース ライセンスは安全です。

于 2012-11-01T12:18:55.450 に答える
1

私の2ペンスの価値を追加します。テンプレートを処理しているので、特定のセルが DateTime であることを知っています。したがって、このメソッドでは、セル値を含む文字列パラメーター excelDateTime を使用します。これは通常、「42540.041666666664」のような OADate 数値になります。

public static bool TryParseExcelDateTime(string excelDateTimeAsString, out DateTime dateTime)
{
    double oaDateAsDouble;
    if (!double.TryParse(excelDateTimeAsString, out oaDateAsDouble)) //this line is Culture dependent!
        return false;
    //[...]
    dateTime = DateTime.FromOADate(oaDateAsDouble);

私の問題は、エンド ユーザーがドイツにいることです。これは Web サイトであるため、Thread.CurrentThread.CurrentCulture と Thread.CurrentThread.CurrentUICulture を「DE-de」に設定しました。を呼び出すとdouble.TryParse、カルチャを使用して数値が解析されます。したがって、この行:double.TryParse("42540.041666666664", out oaDate)は確かに機能します42540041666666664が、ドイツではドットがグループ区切りであるため、返されます。DateTime.FromOADate数値が範囲外であるため失敗します ( minOaDate = -657435.0, maxOaDate = +2958465.99999999 )。

これは私に次のように思わせます:

  1. ユーザーのマシンのロケールに関係なく、OpenXML ドキュメントには、デフォルトのロケールでフォーマットされた数値が含まれています (US? 不変? いずれの場合も、小数点としてドットを使用します)。検索しましたが、これの仕様は見つかりませんでした。
  2. 可能性のあるOADatedouble.TryParse文字列を処理する場合は、 を使用する必要がありますdouble.TryParse(excelDateTimeAsString, NumberStyles.Any, CultureInfo.InvariantCulture, out oaDateAsDouble))。私はCultureInfo.InvariantCultureを使用していますが、ポイント1が何であるかはわかりません。
于 2016-11-23T14:31:31.323 に答える
-1

各セルには、r (CellReference) と s(StyleIndex) の 2 つのプロパティがあります。

数値の StyleIndex は 2、日付の StyleIndex は 3

日付は ODate であり、文字列形式に変換できます

値 = DateTime.FromOADate(double.Parse(値)).ToShortDateString();

于 2016-12-28T17:18:40.387 に答える