S-JIS[2014-10-05/2015-08-27] 変更履歴

Apache POI CellStyle

POI3.10のセルのスタイルを扱う方法について。


概要

Excelのセルのスタイル(罫線や背景色等)はCellStyleインターフェースで扱う。

import org.apache.poi.ss.usermodel.CellStyle;

CellStyleの内容自身はWorkbookで保持しており、同じスタイルを複数のセルに適用したい場合は同じCellStyleインスタンスを使うことが出来る。


スタイルの作成

CellStyleインスタンスを生成するには、Workbook#createCellStyle()を使う。

import org.apache.poi.ss.usermodel.CellStyle;
		CellStyle style = workbook.createCellStyle();
		cell.setCellStyle(style);

複数のセルに同じスタイルを適用したい場合は、作成したCellStyleインスタンスを共用する(使い回す)ことが出来る。


スタイルの取得

セルのスタイルを取得するには、Cell#getCellStyle()を使う。

import org.apache.poi.ss.usermodel.CellStyle;
		CellStyle style = cell.getCellStyle();

getCellStyle()は(何もスタイルがセットされていなくても)必ずインスタンスを返す(nullは返らない)。
(HSSFWorkbookのセル(EXCEL97用のHSSFCell)の場合、呼ぶ度に異なるインスタンスを返す)
(XSSFWorkbookのセル(EXCEL2007用のXSSFCell)の場合、実装を見るとnullが返る可能性もありそうだが、nullが返るのは異常な場合だけなのかも)


スタイルのコピー

スタイルをコピーすることが出来る。[2014-10-06]

		CellStyle commonStyle = 〜;
		CellStyle style = workbook.createCellStyle();
		style.cloneStyleFrom(commonStyle);

フォントの設定

文字に色を付けたり下線(アンダーライン)を引いたりするには、フォントを設定する。[2014-10-06]

import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.IndexedColors;
		Font font = workbook.createFont();
		font.setColor(IndexedColors.BLUE.getIndex()); // 文字色
		font.setUnderline(Font.U_SINGLE); // 下線
		style.setFont(font);

背景色の設定

セルの背景色はsetFillForegroundColor()で設定する。

import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.IndexedColors;
		CellStyle style = workbook.createCellStyle();
		style.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
		style.setFillPattern(CellStyle.SOLID_FOREGROUND); // 塗りつぶし

		cell.setCellStyle(style);

背景パターンも指定してやらないと反映されない。(デフォルトはCellStyle.NO_FILL(塗りつぶし無し)なのだろう)

setFillBackgroundColor()というメソッドもある。これは、背景パターンが単なる塗りつぶしでない場合に意味が出てくると思われる。(古いExcelでは無関係っぽい)


罫線(枠線)の設定

セルの罫線(枠線)は、上下左右を別々のメソッドで設定する。

import org.apache.poi.ss.usermodel.CellStyle;
		CellStyle style = workbook.createCellStyle();
		style.setBorderTop(CellStyle.BORDER_THIN);
		style.setBorderBottom(CellStyle.BORDER_THIN);
		style.setBorderLeft(CellStyle.BORDER_THIN);
		style.setBorderRight(CellStyle.BORDER_THIN);

		cell.setCellStyle(style);

各メソッドの引数で線の太さを指定する。

定数 意味
NONE 線なし
BORDER_THIN
BORDER_MEDIUM 太線

スタイルの変更

セルのスタイルを変更する方法について。[2015-08-27]

セルのスタイルを変更する場合、単純に考えれば、セルからスタイルを取得し、値を変更すればいい。
ただし、Excel内部ではスタイルは番号によって管理されており、同じ番号のスタイルが複数のセルに適用されている場合がある。この場合、スタイルを変更すると、適用されている全てのセルが同じように変更されてしまう。
したがって、取得したスタイルをコピーして新しいスタイルを作り、その値を変更してセルにセットし直せばいい。
が、新しいスタイルを作ると新しい番号が割り当てられる。スタイルは4000個程度しか定義できないらしいので、同じ形式のスタイルがあったら定義済みのスタイルを使うようにするべき。
ただし、同じ形式のスタイルが定義済みかどうかを簡単に判別する方法は無いorz


スタイルの一部だけを変更する場合、CellUtilを使うと便利かもしれない。
これだと、変更した結果、それと同じ形式のスタイルが既に定義されていれば、それを使ってくれる。

import org.apache.poi.ss.util.CellUtil;
	public void changeCellStyle(Cell cell, Cell sourceCell) {
		cell.setCellStyle(sourceCell.getCellStyle());
		CellUtil.setCellStyleProperty(cell, cell.getSheet().getWorkbook(), CellUtil.BORDER_TOP, CellStyle.BORDER_MEDIUM);
	}

setCellStyleProperty()では、スタイルを変更したいセル(およびスタイルが保持されているワークブック)と、変更する値を指定する。
変更対象は、CellUtilに定義されている名前で指定する。

なお、フォントを変更したい場合はCellUtil.setFont()を使う。


CellUtil.setCellStyleProperty()の中を見てみると、変更したスタイルと同じ内容の定義済みスタイルを探し、見つかったら定義済みスタイルを使うようになっている。
定義済みスタイルの取得は単純な線形探索。
スタイルの比較方法は、スタイル内の全属性を一旦Mapに保持してからMap内の値を変更し、ワークブック内で保持している定義済みスタイルも同様にMapに変換し、Map同士が等しいかどうかで判定するというもの。
等しいものが見つかれば定義済みスタイルを使用し、見つからなければ新しいスタイルインスタンスを生成する。
これは時間がかかりそうだ(苦笑)

CellStyle#equals()はスタイルの番号が等しいかどうかで判定しているので、属性が同じかどうかを判定することは出来ない。
なので、setCellStyleProperty()はそういう判定方法になっているのだろう。


POI目次へ戻る / Excel操作ライブラリーへ戻る / Java目次へ戻る / 技術メモへ戻る
メールの送信先:ひしだま