2

DATE(year, month, day)セル内に数式を含む xlsx ファイルを使用しています。このセルは日付としてフォーマットされているため、Excel/OpenOffice は適切な日付を表示します。たとえば、セルの内容は'=DATE(2013;1;1)'次のようになります'01.01.2013' 。これまでのところ - とても良い。

このファイルを poi ライブラリで読み取るときは、次のようにします。

XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream(new File("/home/detlef/temp/test.xlsx")));
XSSFSheet sheet = workbook.getSheet("Sheet A");
XSSFCell cell = sheet.getRow(0).getCell(0);
System.out.println(cell.getDateCellValue());

これは出力されます:

Sun Dec 31 00:00:00 CET 1899

POI 3.9 を使用しています。

なぜこれが起こるのか誰か教えてもらえますか?

それを行う方法を見つけました:

if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
   FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
   CellValue evaluate = evaluator.evaluate(cell);
   Date date = DateUtil.getJavaDate(evaluate.getNumberValue());
   System.out.println(date);
}

それは以下を生成します:

Tue Jan 01 00:00:00 CET 2013

とにかくありがとう。

4

1 に答える 1

4

あなたが説明したことはすべて完全に正しく、期待されています

Excel が数式をセルに格納する場合、数式自体 (.xlsx の文字列、または .xls の解析済みトークン形式) を格納するだけでなく、その数式の最後に評価された回答も格納します。これは、Excel が読み込まれるときに、数式の結果を表示するために時間をかけて計算する必要がなく、他のセルと同様に最後の値でそれらをレンダリングできることを意味します。

これが、Apache POI を使用して Excel ファイルに変更を加えた場合、評価を実行してキャッシュされたすべての数式値を更新する必要がある理由です。これにより、そのセルに移動する前に Excel で正しく表示されます。

ただし、Excel には揮発性として定義されている特殊な数式関数がいくつかあります。これらは、たとえば、毎回常に異なる値を返す関数でDATEあり、これらの Excel ではダミー値 (0 または -1 など) をセルに書き込み、ロード時に再評価します。

POI で数式セルの数値を読み取ると、キャッシュされた値が返されます。POIに式を評価させたい場合は、そうしているように、POIに依頼する必要があります

Excel の日付は、1900 年 1 月 1 日または 1904 年 1 月 1 日 (フラグによって異なります) からの小数日として保存されます。-1 の値は 1899 年 12 月 31 日であるため、Excel が -1 を書き込み、それを日付として要求すると、これが表示されます。

于 2013-10-17T09:55:48.383 に答える