日々常々

ふつうのプログラマがあたりまえにしたいこと。

POIを使ってみる/値の扱い

書式の前に値だと思うんだけど、順番はきにしないでください。記事がたまったら整理するかも。バージョンは3.6です。

値というとvalueなんで、そのままsetValueやgetValueで扱えそうなものなんですが、そうも行きません。ExcelVBAでは、大抵の値はRange.Valueで扱えますが、それでもValue2やTextなんかでも取得でき、取得できる内容も変わったりします。Excelファイルを簡単に扱うことに特化しているはずのExcelVBAですら面倒なので、POIだともっと面倒なことになるのは仕方がないところじゃないでしょうか。

とりあえずJavaDocを眺めてください。
Cell (POI API Documentation)

セルへの値の設定は Cell#setCellValue を使用します。このメソッドオーバーロードされていますので、値の設定に関しては特に困ることはないでしょう。パラメータの型はString、double、boolean、Date、Calendar、RichTextStringになっています。RichTextStringはとりあえず措いておくとして、他は大体イメージどおりだと思います。
オーバーロード出来るsetterは良いのですが、getterはそうも行きません。見てのとおり、値の取得にはそれぞれ専用のメソッドが用意されています。Cell#getStringCellValue、Cell#getNumericCellValueなどです。これらが厄介なのは、そのセルから値を取得する際に、対応するメソッドを使用しなければならないという点です。
例えば、数値を持っているHSSFCellからgetStrincCellValueで値をとろうとすれば、以下の例外が発生します。

java.lang.IllegalStateException: Cannot get a text value from a numeric cell
	at org.apache.poi.hssf.usermodel.HSSFCell.typeMismatch(HSSFCell.java:637)
	at org.apache.poi.hssf.usermodel.HSSFCell.getRichStringCellValue(HSSFCell.java:714)
	at org.apache.poi.hssf.usermodel.HSSFCell.getStringCellValue(HSSFCell.java:697)
	at Test.main(Test.java:29)

よって、Cellから値を取得したい場合は、Cell#getCellTypeで何を扱っているCellかを判定してから取得する必要があります。この際、日付は数値となります。これはExcelも、日付データに対して書式変換をかけて日付に見せているに過ぎないためです。よって、日付セルを扱う場合は、Cell#setCellValue(Date)だけでなく、Cell#setCellStyleで日付書式を設定する必要があります。

Excel表計算ソフトなので、数式を入れることも出来ます。数式の扱いには、getCellFormula/setCellFormulaを使い、パラメータはStringです。数式を入れるからといって、先頭に「=」は不要です。Cell#setCellFormulaで設定するのはあくまで数式のみです。入れると怒られます。以下は「=A1」を入れようとした場合。例外メッセージもそのままなので、原因はすぐわかると思いますが。

org.apache.poi.ss.formula.FormulaParseException: The specified formula '=A1' starts with an equals sign which is not allowed.
	at org.apache.poi.ss.formula.FormulaParser.expected(FormulaParser.java:217)
	at org.apache.poi.ss.formula.FormulaParser.parseSimpleFactor(FormulaParser.java:1117)
	at org.apache.poi.ss.formula.FormulaParser.percentFactor(FormulaParser.java:1072)
	at org.apache.poi.ss.formula.FormulaParser.powerFactor(FormulaParser.java:1059)
	at org.apache.poi.ss.formula.FormulaParser.Term(FormulaParser.java:1410)
	at org.apache.poi.ss.formula.FormulaParser.additiveExpression(FormulaParser.java:1510)
	at org.apache.poi.ss.formula.FormulaParser.concatExpression(FormulaParser.java:1494)
	at org.apache.poi.ss.formula.FormulaParser.comparisonExpression(FormulaParser.java:1451)
	at org.apache.poi.ss.formula.FormulaParser.unionExpression(FormulaParser.java:1431)
	at org.apache.poi.ss.formula.FormulaParser.parse(FormulaParser.java:1552)
	at org.apache.poi.ss.formula.FormulaParser.parse(FormulaParser.java:174)
	at org.apache.poi.hssf.model.HSSFFormulaParser.parse(HSSFFormulaParser.java:72)
	at org.apache.poi.hssf.usermodel.HSSFCell.setCellFormula(HSSFCell.java:588)
	at Test.main(Test.java:31)