JavaでMicrosoft Officeの各種ファイルを扱う場合は Apache POI を使います。
今回はExcelのセルの内容を取得するサンプルを調べました。
セルのテキストを取得
Sheet
クラスが Iterable<Row>
を実装しているので拡張for文で1行ずつなめつつ CellReference#formatAsString()
でテキストを取得。
// import org.apache.poi.ss.usermodel.*;
Sheet sheet1 = wb.getSheetAt(0);
for (Row row : sheet1) {
for (Cell cell : row) {
CellReference cellRef = new CellReference(row.getRowNum(), cell.getColumnIndex());
System.out.print(cellRef.formatAsString());
System.out.print(" - ");
switch (cell.getCellType()) {
case Cell.CELL_TYPE_STRING:
System.out.println(cell.getRichStringCellValue().getString());
break;
case Cell.CELL_TYPE_NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
System.out.println(cell.getDateCellValue());
} else {
System.out.println(cell.getNumericCellValue());
}
break;
case Cell.CELL_TYPE_BOOLEAN:
System.out.println(cell.getBooleanCellValue());
break;
case Cell.CELL_TYPE_FORMULA:
System.out.println(cell.getCellFormula());
break;
default:
System.out.println();
}
}
}
特定のセルに設置された画像の取得
CTDrawing
オブジェクトに画像のアンカー情報がセルの座標で記録されてるが、内部APIを使わないと取得できないので、XSSFWorkbook#getAllPictures()
のソース http://git.io/mKdmpw を参考に以下のように CTDrawing オブジェクトをなめる処理を書く。
やってみたら CTDrawing#getTwoCellAnchorList()
がNoClassFoundErrorとかで全然動かない。
半ばキレ気味に調査した結果、XSSFDrawing#getShapes()
で XSSFShape オブジェクトを取得して XSSFPicture クラスにキャストすると座標がとれることが分かった。
ただし Apache POI 3.9 以降でないと使えない。
// シートに添付されている画像を収集
for (POIXMLDocumentPart dr : ((POIXMLDocumentPart) sheet).getRelations()) {
if (dr instanceof XSSFDrawing) {
XSSFDrawing xfd = (XSSFDrawing)dr;
for (XSSFShape shape : xfd.getShapes()){
if (shape instanceof XSSFPicture) {
XSSFClientAnchor xca = ((XSSFPicture) shape).getPreferredSize();
// 画像が設置されているセルの左上座標を取得
int row = xca.getRow1();
int col = xca.getCol1();
}
}
}
}
余談
POI は Poor Obfuscation Implementation (質の悪い難読な実装) の略とのこと。
また HSSF は Horrible Spread Sheet Format (ひどい表計算フォーマット) とのことで、ネーミングに邪念を感じる。
リンク
Busy Developers' Guide to HSSF and XSSF Features
http://poi.apache.org/spreadsheet/quick-guide.html
APIドキュメント
http://poi.apache.org/apidocs/