SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

最新POIでOffice Open XML形式のExcelファイルを操作

「Usermodel API」を利用したExcelファイルの基本操作

最新POIでOffice Open XML形式のExcelファイルを操作 第2回

  • X ポスト
  • このエントリーをはてなブックマークに追加

共通インターフェースAPI

 ソース1のプログラムはOOXML形式のファイルだけを扱うのであれば問題ありませんが、既存のOLE2形式のファイルも同時にサポート可能にしたい場合には対応できません。そこで、そのような要望に応えるためにPOI3.5から共通インターフェースを提供する「org.apache.poi.ss.usermodel」パッケージ(以降SSパッケージ)が導入されています。

 SSパッケージにはXSSFとHSSFの共通のインターフェースが定義されており、SSパッケージのインターフェース群を利用することで、HSSFかXSSFを明示的に指定することなくUsermodel APIを利用できます。

 前回紹介しましたサンプルプログラム「TimesheetDemoクラス」から一部抜粋したソースで確認してみましょう。

ソース2
public static void main(String[] args) throws Exception {
    //(1)Workbookインターフェースの宣言
    Workbook wb;
    
    //(2)Workbookインターフェースへの代入
    if(args.length > 0 && args[0].equals("-xls")) wb = new HSSFWorkbook();
    else wb = new XSSFWorkbook();

    Map<String, CellStyle> styles = createStyles(wb);

    //(3)Sheetインターフェースへの代入
    Sheet sheet = wb.createSheet("Timesheet");
    PrintSetup printSetup = sheet.getPrintSetup();
    printSetup.setLandscape(true);
    sheet.setFitToPage(true);
    sheet.setHorizontallyCenter(true);

    //(4)Rowインターフェースへの代入
    Row titleRow = sheet.createRow(0);
    titleRow.setHeightInPoints(45);

    //(5)Cellインターフェースへの代入
    Cell titleCell = titleRow.createCell(0);
    titleCell.setCellValue("Weekly Timesheet");
    titleCell.setCellStyle(styles.get("title"));
    sheet.addMergedRegion(CellRangeAddress.valueOf("$A$1:$L$1"));
  • ソース2 -(1)
  •  SSパッケージが提供するWorkbookインターフェースを宣言しています。

  • ソース2 -(2)
  •  引数の値に応じて、HSSFかXSSFのワークブックオブジェクトをWorkbookインターフェースに代入しています。どちらのワークブックオブジェクトが選択されても共通のWorkbookインターフェースに格納できることが確認できます。

  • ソース2 -(3)、(4)、(5)
  •  いったんワークブックインターフェースにHSSFかXSSFのワークブックオブジェクトが代入された後は、「HSSF」や「XSSF」名がついたシート、行、セルオブジェクトはソース上には現れません。すべてインターフェースが代わりに利用されています。各インターフェースではUsermodel APIのメソッドが利用できています。なお、セルスタイルやフォント等の他のオブジェクトに関しても共通インターフェースがSSパッケージで提供されています。

WorkbookFactoryクラス

 次に既存のExcelファイルを読み込んで利用するために用意されているAPIを確認しましょう。XSSFワークブックを読込む方法としては、次のコンストラクタが用意されています。

public XSSFWorkbook(java.io.InputStream is) throws java.io.IOException

 一方、既存のHSSFワークブックを読み込む方法としては、次のコンストラクタが用意されていました。

public HSSFWorkbook(java.io.InputStream is) throws java.io.IOException

 コンストラクタ内の処理をソースで確認してみると、XSSFでは「OPCPackage」が利用され、HSSFでは「POIFSFileSystem」が利用されているという違いがあるのですが、メソッドの呼出しだけの観点で言えば、「XSSFWorkbook」か「HSSFWorkbook」のいずれかのコンストラクタの名称を明確に指定するだけの違いです。

 ただし、OOXMLとOLE2形式の両方のExcelファイルに対応するのであれば、SSパッケージで用意されている「WorkbookFactory」クラスを利用すると便利です。InputStreamオブジェクトを引数に渡すだけでXSSFWorkbookなのかHSSFWorkbookなのかを自動で判断して、適切なワークブックオブジェクトを生成後、Workbookインターフェースとして提供してくれます。サンプルプログラムで確認してみましょう。

ソース3
import java.io.FileInputStream;
import java.io.InputStream;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;

public class ReadWorkbook {

    /**
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {

        //(1)入力ファイル名の取得
        String fileName = args[0];
        InputStream inp = new FileInputStream(fileName);

        //(2)入力ファイルを表すワークブックオブジェクトの生成
        Workbook wb = WorkbookFactory.create(inp);

        // シート数分繰返す
        for (int i = 0; i < wb.getNumberOfSheets(); i++) {
            Sheet sheet = wb.getSheetAt(i);
            System.out.println(wb.getSheetName(i));

            // 行数分繰返す
            for (Row row : sheet) {
                System.out.println("rownum: " + row.getRowNum());

                for (Cell cell : row) {
                    String cellValue = null;
                    int cellType = cell.getCellType();
                    
                    switch (cellType) {
                    case Cell.CELL_TYPE_BOOLEAN:
                        boolean bValue = cell.getBooleanCellValue();
                        cellValue = String.valueOf(bValue);
                        break;
                    case Cell.CELL_TYPE_NUMERIC:
                        double dValue = cell.getNumericCellValue();
                        cellValue = String.valueOf(dValue);
                        break;
                    case Cell.CELL_TYPE_STRING:
                        cellValue = cell.getStringCellValue();
                        break;
                    case Cell.CELL_TYPE_BLANK:
                    case Cell.CELL_TYPE_ERROR:
                    case Cell.CELL_TYPE_FORMULA:
                    default:
                        continue;
                    }
                    // セル値の出力
                    System.out.println(cellValue);
                }
            }
        }
    }
}
  • ソース3 -(1)
  •  変数fileNameに引数を使って読込みたい入力ファイル名(「xlsx」または「xls」の拡張子付き)を代入します。

  • ソース3 -(2)
  •  fileNameに代入したファイルの拡張子が「xlsx」であれば「XSSFWorkbook」が生成され、「xls」であれば「HSSFWorkbook」が自動で生成されます。戻り値はSSパッケージのWorkbookインターフェースです。

 ソース上には「XSSF」や「HSSF」を明示的に指定する箇所や、コンポーネントの違いにより分岐処理をしている箇所はありません。

 その後の処理は読込んだワークブックに含まれるワークシートごとに、各行を走査し、セルを表すオブジェクトを取得しています。そして、取得したセルの種類(論理型/数値型/文字列型)に応じて、セル値を取得し、文字列としてコンソールに出力しています。処理の途中でワークシート名や行番号も出力していますが、行番号は、書式設定の変更や値を設定したセルを含んでいる行だけが行番号が表示されます。それ以外の行オブジェクトはNullということになります。

次のページ
CreationHelperインターフェース

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
最新POIでOffice Open XML形式のExcelファイルを操作連載記事一覧

もっと読む

この記事の著者

土田 将人(ツチダ マサト)

株式会社ビーブレイクシステムズにて業務システムのパッケージソフト(MA-EYES)の製品開発に従事。英語や会計等、システム開発以外のスキルを活かして官公庁やメーカ系のシステム開発で活躍中。少し前に、パッケージソフトMA-EYESの開発を通して「POI」を知り尽くし、勢い余って本稿の執筆に至る。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/4881 2010/03/01 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング