読み込み処理の流れ
さて、続いてストリーム関係と、POIのファイルシステムに関するクラスの準備に入ります。今回は、FileInputStreamとBufferedInputStreamを利用します。
FileInputStream input = null;
BufferedInputStream binput = null;
POIFSFileSystem poifs = null;
ストリーム関係はわかりますね。最後の「POIFSFileSystem」というのが、ファイルの読み込みで必要となるクラスです。これはPOIで利用されるファイルシステム関係のクラスで、読み込みの場合のみ必要となります。
input = new FileInputStream(fname);
binput = new BufferedInputStream(input);
poifs = new POIFSFileSystem(binput);
FileインスタンスからFileInputStreamを作成し、これを使ってBufferedInputStreamを作ります。更に、このBufferedInputStreamを引数に指定して、POIFSFileSystemインスタンスを作成します。
HSSFWorkbook workbook = new HSSFWorkbook(poifs);
では、ワークブックを作成しましょう。new HSSFWorkbookする際に、引数にPOIFSFileSystemインスタンスを引き渡します。こうすることで、このPOIFSFileSystemの入力ストリーム(Fileを指定したFileInputStream)からデータを読み込んでHSSFWorkbookを生成することができます。
HSSFSheet sheet = workbook.getSheetAt(0);
作成したHSSFWorkbookから、最初のシート(HSSFSheet)を取得します。これは、「getSheetAt」というメソッドを使います。このメソッドは、指定のインデックス番号のシートを示すHSSFSheetを返します。似たようなものに「getSheet」というメソッドもあり、こちらはシート名でHSSFSheetを取得することができます。
int rows = sheet.getLastRowNum();
rows = rows > (row_num - 1) ? row_num - 1 : rows;
シートから、行データを取得していきます。「getLastRowNum」は、最後の行番号を返すメソッドです。これで最後の行を調べます。ただし、JTableより大きすぎると困るので、JTableに用意したセル数を超えていたら調整をしておきます。
for(int i = 0;i < rows;i++){
HSSFRow row = sheet.getRow(i);
if (row == null) continue;
int cols = row.getLastCellNum();
cols = cols > col_num ? col_num : cols;
繰り返しに入り、HSSFSheetの「getRow」メソッドで指定したインデックス番号のHSSFRowを取得します。そして、getLastCellNumで最後のセルの番号を取り出します。これもやはりJTableのモデルに入りきらなかったら値を調整しておきます。
for(int j = 0;j <= cols;j++){
HSSFCell cell = row.getCell((short)j);
if (cell == null) continue;
続いて第2の繰り返しに入り、HSSFRowの「getCell」で指定したインデックス番号のHSSFCellを取得します。こうしてセルを得たら、ここから値を取り出してJTableのモデルに設定していけばいいのですね。が、ここでもちょっと一ひねりが必要になります。
if (cell.getCellType() == HSSFCell.CELL_TYPE_STRING){
HSSFRichTextString val = cell.getRichStringCellValue();
table.getModel().setValueAt(val,i,j);
}
実は、各セルには「種類」があるのです。テキストのセル、数値のセル、真偽値のセル、というように、それぞれに設定されている値によってセルの種類は異なります。そこで、各種類ごとに値を取り出していかなければいけません。
セルの種類は、「getCellType」で得ることができます。HSSFCellには、セルの種類を示す値がクラスフィールドとして用意されています。ここでは、getCellTypeされた値が、HSSFCell.CELL_TYPE_STRINGかどうかをチェックしていますね。これは、テキストのセルであることを示すものです。テキストセルだった場合には、「getRichStringCellValue」メソッドでHSSFRichTextStringインスタンスとして値を取り出し、モデルに設定をします。
if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC){
double val = cell.getNumericCellValue();
table.getModel().setValueAt(val,i,j);
}
続いて、セルが数値セルかどうかをチェックします。数値セルは、getCellTypeの値がHSSFCell.CELL_TYPE_NUMERICとなります。この場合は、「getNumericCellValue」メソッドを呼び出し、値をdouble値として取り出します。
とりあえず、ここではテキストと数値についてのみ処理してありますが、セルの種類に応じてこうした処理を更に追加していくことになります。そして、すべての読み込みが終わったら、入力ストリームをcloseして作業終了です。
読み込みは、書き出しよりも意外に手間がかかります。特にセルの種類についてはひっかかりがちなので注意しましょう。セルの種類とは異なる値を取り出そうとすると例外を発生させてしまいますから。