Help us understand the problem. What is going on with this article?

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

More than 5 years have passed since last update.

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/

unicast
ユニキャストは、茨城大学工学部発の学生ベンチャー企業として、2005年に産声をあげました。 ミッションである『テクノロジを通じて「驚き」と「感動」を創造し、人々の「夢」と「希望」を支えます。』を合言葉に、これからも幅広く価値発信してまいります。
http://www.unicast.ne.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away