1. 序章

JavaでExcelファイルを読み取る場合、通常、セルの値を読み取って計算を実行したり、レポートを生成したりします。 ただし、生データ値ではなく数式を含む1つ以上のセルに遭遇する場合があります。 では、これらのセルの実際のデータ値をどのように取得するのでしょうか。

このチュートリアルでは、 Apache POI Javaライブラリを使用して、セル値を計算する数式ではなく、Excelのセル値を読み取るさまざまな方法を見ていきます。

この問題を解決するには、次の2つの方法があります。

  • セルの最後にキャッシュされた値を取得します
  • 実行時に数式を評価して、セルの値を取得します

2. Mavenの依存関係

ApachePOIのpom.xmlファイルに次の依存関係を追加する必要があります。

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.2.0</version>
</dependency>

poi-ooxml の最新バージョンは、MavenCentralからダウンロードできます。

3. 最後にキャッシュされた値を取得する

Excelは、数式がその値を計算するときに、セルの2つのオブジェクトを格納します。 1つは数式自体で、もう1つはキャッシュされた値です。 キャッシュされた値には、式によって評価された最後の値が含まれます。

したがって、ここでの考え方は、最後にキャッシュされた値をフェッチして、それをセル値と見なすことができるということです。 最後にキャッシュされた値が正しいセル値であるとは限らない場合があります。 ただし、保存されているExcelファイルを操作していて、ファイルに最近変更がない場合は、最後にキャッシュされた値がセルの値になります。

セルの最後にキャッシュされた値をフェッチする方法を見てみましょう。

FileInputStream inputStream = new FileInputStream(new File("temp.xlsx"));
Workbook workbook = new XSSFWorkbook(inputStream);
Sheet sheet = workbook.getSheetAt(0);

CellAddress cellAddress = new CellAddress("C2");
Row row = sheet.getRow(cellAddress.getRow());
Cell cell = row.getCell(cellAddress.getColumn());

if (cell.getCellType() == CellType.FORMULA) {
    switch (cell.getCachedFormulaResultType()) {
        case BOOLEAN:
            System.out.println(cell.getBooleanCellValue());
            break;
        case NUMERIC:
            System.out.println(cell.getNumericCellValue());
            break;
        case STRING:
            System.out.println(cell.getRichStringCellValue());
            break;
    }
}

4. 数式を評価してセル値を取得する

Apache POIは、 FormulaEvaluatorクラスを提供します。これにより、Excelシートで数式の結果を計算できます。

したがって、 FormulaEvaluator を使用して、実行時にセル値を直接計算できます。 FormulaEvaluator クラスは、 EvaluationFormulaCell、というメソッドを提供します。このメソッドは、指定された Cell オブジェクトのセル値を評価し、CellTypeオブジェクトを返します。セル値のデータ型を表します。

このアプローチの実際を見てみましょう。

// existing Workbook setup

FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator(); 

// existing Sheet, Row, and Cell setup

if (cell.getCellType() == CellType.FORMULA) {
    switch (evaluator.evaluateFormulaCell(cell)) {
        case BOOLEAN:
            System.out.println(cell.getBooleanCellValue());
            break;
        case NUMERIC:
            System.out.println(cell.getNumericCellValue());
            break;
        case STRING:
            System.out.println(cell.getStringCellValue());
            break;
    }
}

5. どのアプローチを選択するか

ここでの2つのアプローチの単純な違いは、最初のメソッドは最後にキャッシュされた値を使用し、2番目のメソッドは実行時に数式を評価することです。

すでに保存されているExcelファイルを使用していて、実行時にそのスプレッドシートに変更を加えない場合は、数式を評価する必要がないため、キャッシュ値アプローチの方が適しています。

ただし、実行時に頻繁に変更を加えることがわかっている場合は、実行時に数式を評価してセル値を取得することをお勧めします。

6. 結論

この簡単な記事では、Excelセルの値を計算する数式ではなく、2つの方法でExcelセルの値を取得する方法について説明しました。

この記事の完全なソースコードは、GitHubで入手できます