LoginSignup
12
14

More than 5 years have passed since last update.

Apache POI でExcelのセルの内容(テキスト・画像)を取得する

Last updated at Posted at 2015-03-02

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/

12
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
14