2010年08月13日

POIでセルの値をとるのは大変 数値(通貨)編

一般的に紹介されている取得方法では、(私の)意図したとおりに取得できなかったので、POIでセルの値を見た目どおりに取得する方法について数回に分けて記載します。

どんな場合に問題になるのでしょうか?
セルの値を取得する際に、セルのタイプを把握して適したメソッドを使用しないと例外が発生してしまいます。
このあたりはあちこちのページで紹介されているので困惑することはありません。
しかし、セルが数値タイプや日付タイプで書式が設定されており、表示されているとおりにStringでほしい場合など、問題が顕著になります。
例えばセルに「-12345.00」という値が設定されており、書式が「▲1,234」だった場合に、
  double value = cell.getNumericCellValue();
  String retValue = String.valueOf(value);
とすると、retValueには「-12345.00」が詰められます。
欲しいのは表示どおりの「▲12,345」だったとしても自分で変換しなければなりません。
すべてのセルについてコーディング時に把握できていれば解決できますが、
ユーザが入力するExcelファイルを読み込む場合には、なかなか難しいのが現実ではないでしょうか。

ではどうやって解決すればよいのでしょう?
結論としては DataFormatter#formatCellValue() を使いました。
  DataFormatter formatter = new DataFormatter();
  String retValue = formatter.formatCellValue(cell);
とすると、表示している内容を取得できます。
ところがこれですべてが解決すれば問題はないのですが、
このformatCellValue()が曲者で、場合によってはまともに返してくれません。
通貨「-¥123,456」の書式で設定したセルから帰ってくる値は、
なんと「($123,456)」!!
驚きですが、ステップ実行するとHSSFDataFormat#getFormat()が直接の原因であることがわかります。
(根本原因はフォーマットのインデックス番号にありそう)
BuiltinFormatsクラスから先に検索して、フォーマットのインデックスが存在する値「($123,456)」を返してしまいます。
結局すべてを救うことを断念し、概ね使えているということで上記方法で妥協しました。
もともとフォーマットで負数を赤字にしているフォーマットは救いようがないこともあるので、どこかに線引きが必要です。
あと1点、曲者のformatCellValue()は文字列「_ 」を最後につけて返すことがあります。
これらのことを踏まえて最終的なソースは下記のようにしました。
  DataFormatter formatter = new DataFormatter();
  String retValue = formatter.formatCellValue(cell);
  if (retValue.endsWith("_ ")) {
    retValue = retValue.substring(0, retValue.length() -2);
  }

それでは表示どおりの値で取得できるフォーマットとは?
下記に取得できるフォーマット、できない場合にどのような値になるかを表にしてみました。
フォーマット 表示どおり取得可能 不可能だった際の取得フォーマット
標準(数値)
標準(文字列)
数値((1,234)
数値((1,234))
数値(1,234×-1234
数値(-1,234)
数値(-1,234
数値(△1,234)
数値(▲1,234)
数値((1234.56)
数値((1234.56))
数値(1234.56×-1234.56
数値(-1234.56)
数値(-1234.56
数値(△1234.56)
数値(▲1234.56)
通貨((¥123,456)×(123,456)
通貨((¥123,456))×(123,456)
通貨(¥123,456×-123,456
通貨(-¥123,456)×($123,456)
通貨(-¥123,456×($123,456)
通貨((¥123,456.78)×(123,456.78)
通貨((¥123,456.78))×(123,456.78)
通貨(¥123,456.78×-123,456.78
通貨(-¥123,456.78)×($123,456.78)
通貨(-¥123,456.78×($123,456.78)
会計(¥)×-123456
会計×-123456
会計(¥ 少数2桁)×-123456.78
会計(少数2桁)×-123456.78
パーセンテージ
パーセンテージ(少数2桁)
ラベル:java Poi
posted by しん at 12:51| Comment(0) | POI | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。