Apache POIチュートリアル
「Apache POIチュートリアルへようこそ。時には、マイクロソフトエクセルファイルからデータを読み取る必要がある場合や、主にビジネスや金融目的でエクセル形式のレポートを作成する必要があります。JavaにはExcelファイルを操作するための組み込みサポートは提供されていないため、私たちはこの仕事のためのオープンソースAPIを探す必要があります。Java向けのExcel用のAPIを探し始めたとき、ほとんどの人々がJExcelまたはApache POIをおすすめしました。さらなる調査の結果、Apache POIが主要な理由から進むべき道であることがわかりました。高度な機能に関連する他の理由もありますが、詳細には触れませんでした。」
- Backing of Apache foundation.
- JExcel doesn’t support xlsx format whereas POI supports both xls and xlsx formats.
- Apache POI provides stream-based processing, that is suitable for large files and requires less memory.
アパッチ POI
Apache POIはMicrosoft Excelドキュメントを扱う際に優れたサポートを提供します。Apache POIはスプレッドシートのXLSおよびXLSX形式の両方を扱うことができます。Apache POI APIの重要なポイントは以下の通りです。
-
- Apache POIには、Excel ’97(-2007)のファイル形式であるXLSのHSSF実装が含まれています。
-
- Excel 2007のOOXML (.xlsx)ファイル形式には、Apache POIのXSSF実装を使用する必要があります。
-
- Apache POIのHSSFとXSSF APIは、Excelスプレッドシートを読み取ったり、書き込んだり、変更したりするための仕組みを提供します。
-
- Apache POIはSXSSF APIも提供しており、非常に大きなExcelシートを扱うためのXSSFの拡張です。SXSSF APIはメモリを少なく使用し、ヒープメモリが制限されている場合に適しています。
-
- 選択できるモデルは2つあります – イベントモデルとユーザーモデルです。イベントモデルは、Excelファイルをトークンとして読み込み、それらを処理する必要があるため、メモリを少なく使用します。ユーザーモデルはオブジェクト指向であり、使用が簡単です。私たちはこのユーザーモデルを使用します。
- Apache POIは、式の操作、色や境界線の設定によるセルスタイルの作成、フォント、ヘッダーとフッター、データの検証、画像、ハイパーリンクなど、追加のExcel機能の優れたサポートも提供しています。
Apache POIのMaven依存関係
もしMavenを使用している場合は、以下のApache POIの依存関係を追加してください。
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.10-FINAL</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.10-FINAL</version>
</dependency>
現在のApache POIのバージョンは3.10-FINALです。もし単体のJavaアプリケーションを使用している場合は、以下の画像からJARファイルを取り込んでください。
Apache POI の例 – Excel ファイルの読み取り例
「Sample.xlsx」というエクセルファイルがあり、以下の画像のようなデータが2つのシートに含まれているとします。このエクセルファイルを読み込み、国のリストを作成したいです。Sheet1にはパースする際に無視するべき追加のデータがあります。国のJava Beanコードは、Country.javaです。
package com.scdev.excel.read;
public class Country {
private String name;
private String shortCode;
public Country(String n, String c){
this.name=n;
this.shortCode=c;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getShortCode() {
return shortCode;
}
public void setShortCode(String shortCode) {
this.shortCode = shortCode;
}
@Override
public String toString(){
return name + "::" + shortCode;
}
}
下記のようなExcelファイルを国のリストに読み込むためのApache POIのサンプルプログラムは、ReadExcelFileToList.javaという名前です。
package com.scdev.excel.read;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
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.xssf.usermodel.XSSFWorkbook;
public class ReadExcelFileToList {
public static List<Country> readExcelData(String fileName) {
List<Country> countriesList = new ArrayList<Country>();
try {
//Create the input stream from the xlsx/xls file
FileInputStream fis = new FileInputStream(fileName);
//Create Workbook instance for xlsx/xls file input stream
Workbook workbook = null;
if(fileName.toLowerCase().endsWith("xlsx")){
workbook = new XSSFWorkbook(fis);
}else if(fileName.toLowerCase().endsWith("xls")){
workbook = new HSSFWorkbook(fis);
}
//Get the number of sheets in the xlsx file
int numberOfSheets = workbook.getNumberOfSheets();
//loop through each of the sheets
for(int i=0; i < numberOfSheets; i++){
//Get the nth sheet from the workbook
Sheet sheet = workbook.getSheetAt(i);
//every sheet has rows, iterate over them
Iterator<Row> rowIterator = sheet.iterator();
while (rowIterator.hasNext())
{
String name = "";
String shortCode = "";
//Get the row object
Row row = rowIterator.next();
//Every row has columns, get the column iterator and iterate over them
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext())
{
//Get the Cell object
Cell cell = cellIterator.next();
//check the cell type and process accordingly
switch(cell.getCellType()){
case Cell.CELL_TYPE_STRING:
if(shortCode.equalsIgnoreCase("")){
shortCode = cell.getStringCellValue().trim();
}else if(name.equalsIgnoreCase("")){
//2nd column
name = cell.getStringCellValue().trim();
}else{
//random data, leave it
System.out.println("Random data::"+cell.getStringCellValue());
}
break;
case Cell.CELL_TYPE_NUMERIC:
System.out.println("Random data::"+cell.getNumericCellValue());
}
} //end of cell iterator
Country c = new Country(name, shortCode);
countriesList.add(c);
} //end of rows iterator
} //end of sheets for loop
//close file input stream
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
return countriesList;
}
public static void main(String args[]){
List<Country> list = readExcelData("Sample.xlsx");
System.out.println("Country List\n"+list);
}
}
このプログラムは非常に理解しやすく、以下のステップを含んでいます。
-
- ファイルの種類に基づいてWorkbookインスタンスを作成します。xlsx形式の場合はXSSFWorkbookを使用し、xls形式の場合はHSSFWorkbookを使用してください。なお、ファイル名を基にWorkbookインスタンスを取得するために、ファクトリーパターンを使用したラッパークラスを作成することもできます。
-
- getNumberOfSheets()メソッドを使用してシートの数を取得し、それぞれのシートを解析するためにforループを使用してください。getSheetAt(int i)メソッドを使用してSheetインスタンスを取得します。
-
- Rowイテレーターを取得し、Cellイテレーターを使用してCellオブジェクトを取得します。Apache POIでは、ここでイテレーターパターンを使用しています。
- Cellの種類を読み取り、それに応じて処理を行うためにswitch-case文を使用してください。
上記のApache POIの例プログラムを実行すると、コンソール上に次の出力が生成されます。
Random data::1.0
Random data::2.0
Random data::3.0
Random data::4.0
Country List
[India::IND, Afghanistan::AFG, United States of America::USA, Anguilla::AIA,
Denmark ::DNK, Dominican Republic ::DOM, Algeria ::DZA, Ecuador ::ECU]
Apache POIの例 – Excelファイルの書き込み
Apache POIを使用してExcelファイルを書き込むことは、読み込むことと似ていますが、最初にワークブックを作成します。次に、シート、行、セルの値を設定し、FileOutputStreamを使用してファイルに書き込みます。ここでは、前述の方法で得られた国のリストを別のファイルの単一のシートに保存するための簡単なApache POIの例を書いてみましょう。WriteListToExcelFile.java
package com.scdev.excel.read;
import java.io.FileOutputStream;
import java.util.Iterator;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
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.xssf.usermodel.XSSFWorkbook;
public class WriteListToExcelFile {
public static void writeCountryListToFile(String fileName, List<Country> countryList) throws Exception{
Workbook workbook = null;
if(fileName.endsWith("xlsx")){
workbook = new XSSFWorkbook();
}else if(fileName.endsWith("xls")){
workbook = new HSSFWorkbook();
}else{
throw new Exception("invalid file name, should be xls or xlsx");
}
Sheet sheet = workbook.createSheet("Countries");
Iterator<Country> iterator = countryList.iterator();
int rowIndex = 0;
while(iterator.hasNext()){
Country country = iterator.next();
Row row = sheet.createRow(rowIndex++);
Cell cell0 = row.createCell(0);
cell0.setCellValue(country.getName());
Cell cell1 = row.createCell(1);
cell1.setCellValue(country.getShortCode());
}
//lets write the excel data to file now
FileOutputStream fos = new FileOutputStream(fileName);
workbook.write(fos);
fos.close();
System.out.println(fileName + " written successfully");
}
public static void main(String args[]) throws Exception{
List<Country> list = ReadExcelFileToList.readExcelData("Sample.xlsx");
WriteListToExcelFile.writeCountryListToFile("Countries.xls", list);
}
}
上記のApache POIの例のプログラムを実行すると、生成されたExcelファイルは下記の画像のようになります。
Apache POIの例 – Excelの数式を読み取る
時には、複雑なエクセルファイルを扱う必要があります。単純なApache POIの例を見て、セルの数式と値を読み取る方法を確認しましょう。ReadExcelFormula.java
package com.scdev.excel.read;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Iterator;
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.xssf.usermodel.XSSFWorkbook;
public class ReadExcelFormula {
public static void readExcelFormula(String fileName) throws IOException{
FileInputStream fis = new FileInputStream(fileName);
//assuming xlsx file
Workbook workbook = new XSSFWorkbook(fis);
Sheet sheet = workbook.getSheetAt(0);
Iterator<Row> rowIterator = sheet.iterator();
while (rowIterator.hasNext())
{
Row row = rowIterator.next();
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext())
{
Cell cell = cellIterator.next();
switch(cell.getCellType()){
case Cell.CELL_TYPE_NUMERIC:
System.out.println(cell.getNumericCellValue());
break;
case Cell.CELL_TYPE_FORMULA:
System.out.println("Cell Formula="+cell.getCellFormula());
System.out.println("Cell Formula Result Type="+cell.getCachedFormulaResultType());
if(cell.getCachedFormulaResultType() == Cell.CELL_TYPE_NUMERIC){
System.out.println("Formula Value="+cell.getNumericCellValue());
}
}
}
}
}
public static void main(String args[]) throws IOException {
readExcelFormula("FormulaMultiply.xlsx");
}
}
上記のApache POIの例プログラムを実行すると、以下の出力結果が得られます。
1.0
2.0
3.0
4.0
Cell Formula=A1*A2*A3*A4
Cell Formula Result Type=0
Formula Value=24.0
Apache POIの例 – Excelに数式を書き込む
時々、私たちはいくつかの計算をしなければならず、それからセルの値を書く必要があります。私たちはExcelの数式を使用してこの計算を行うことができ、セルの値が変更された場合に値も変更されるため、より正確になります。Apache POI APIを使用してExcelファイルに数式を書くための簡単な例を見てみましょう。WriteExcelWithFormula.java
package com.scdev.excel.read;
import java.io.FileOutputStream;
import java.io.IOException;
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.xssf.usermodel.XSSFWorkbook;
public class WriteExcelWithFormula {
public static void writeExcelWithFormula(String fileName) throws IOException{
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("Numbers");
Row row = sheet.createRow(0);
row.createCell(0).setCellValue(10);
row.createCell(1).setCellValue(20);
row.createCell(2).setCellValue(30);
//set formula cell
row.createCell(3).setCellFormula("A1*B1*C1");
//lets write to file
FileOutputStream fos = new FileOutputStream(fileName);
workbook.write(fos);
fos.close();
System.out.println(fileName + " written successfully");
}
public static void main(String[] args) throws IOException {
writeExcelWithFormula("Formulas.xlsx");
}
}
上記のApache POI APIの例プログラムで生成されたExcelファイルは、以下の画像のようになります。これでExcelファイルの操作に関するApache POIチュートリアルは終わりです。さらなる機能を学ぶために、Apache POIのクラスメソッドを調べてみてください。参考文献: Apache POI開発者ガイド。