Apache POIチュートリアル

ようこそ、Apache POI チュートリアルへ。時々、Microsoft Excel ファイルからデータを読み取ったり、Excel 形式でレポートを生成する必要があります。これは主にビジネスやファイナンスの目的で行われます。Java には Excel ファイルを操作するための組み込みサポートがないため、この作業にはオープンソースの API を探す必要があります。Java の Excel API を探すと、ほとんどの人が JExcel または Apache POI を推奨しています。さらなる調査の結果、Apache POI が最適な選択肢であることがわかりました。その主な理由は以下の通りです。

  • Apache ファンデーションのサポート。
  • JExcel は xlsx 形式をサポートしていませんが、POI は xls と xlsx の両方をサポートしています。
  • Apache POI はストリームベースの処理を提供しており、大きなファイルに適しており、メモリを少なく使用します。

Apache POI

Apache POI は Microsoft Excel ドキュメントを操作するための優れたサポートを提供しています。Apache POI はスプレッドシートの XLS および XLSX 形式の両方を処理できます。Apache POI API に関するいくつかの重要なポイントは次のとおりです:

  1. Apache POI には Excel ’97(-2007) ファイル形式(XLS)用の HSSF 実装が含まれています。
  2. Excel 2007 OOXML (.xlsx) ファイル形式には Apache POI XSSF 実装を使用する必要があります。
  3. Apache POI HSSF および XSSF API には、Excel スプレッドシートの読み取り、書き込み、または変更を行うメカニズムが提供されています。
  4. Apache POIは、非常に大きなExcelシートと連携するためのXSSFの拡張であるSXSSF APIも提供しています。SXSSF APIはメモリを少なく必要とし、ヒープメモリが限られている場合に適しています。
  5. 選択肢は2つあります。イベントモデルとユーザーモデルです。イベントモデルは、Excelファイルがトークンで読み込まれ、それらを処理する必要があるため、メモリを少なく必要とします。ユーザーモデルはオブジェクト指向で使いやすく、私たちはこのモデルを例に取り上げます。
  6. 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.journaldev.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;
	}
	
}

エクセルファイルをリストに読み込むためのApache POIの例は以下のようになります。ReadExcelFileToList.java

package com.journaldev.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 readExcelData(String fileName) {
		List countriesList = new ArrayList();
		
		try {
			//xlsx/xlsファイルから入力ストリームを作成する
			FileInputStream fis = new FileInputStream(fileName);
			
			//xlsx/xlsファイルのためのWorkbookインスタンスを作成する
			Workbook workbook = null;
			if(fileName.toLowerCase().endsWith("xlsx")){
				workbook = new XSSFWorkbook(fis);
			}else if(fileName.toLowerCase().endsWith("xls")){
				workbook = new HSSFWorkbook(fis);
			}
			
			//xlsxファイルのシート数を取得する
			int numberOfSheets = workbook.getNumberOfSheets();
			
			//各シートをループする
			for(int i=0; i < numberOfSheets; i++){
				
				//Workbookからn番目のシートを取得する
				Sheet sheet = workbook.getSheetAt(i);
				
				//各シートには行があり、それらを繰り返し処理する
				Iterator rowIterator = sheet.iterator();
				while (rowIterator.hasNext()) 
		        {
					String name = "";
					String shortCode = "";
					
					//行オブジェクトを取得する
					Row row = rowIterator.next();
					
					//各行には列があり、列イテレータを取得してそれらを繰り返し処理する
					Iterator cellIterator = row.cellIterator();
		             
		            while (cellIterator.hasNext()) 
		            {
		            	//セルオブジェクトを取得する
		            	Cell cell = cellIterator.next();
		            	
		            	//セルのタイプをチェックし、適切に処理する
		            	switch(cell.getCellType()){
		            	case Cell.CELL_TYPE_STRING:
		            		if(shortCode.equalsIgnoreCase("")){
		            			shortCode = cell.getStringCellValue().trim();
		            		}else if(name.equalsIgnoreCase("")){
		            			//2番目の列
		            			name = cell.getStringCellValue().trim();
		            		}else{
		            			//ランダムなデータ、無視する
		            			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
			
			//ファイルの入力ストリームを閉じる
			fis.close();
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return countriesList;
	}

	public static void main(String args[]){
		List list = readExcelData("Sample.xlsx");
		System.out.println("Country List\n"+list);
	}

}

このプログラムは非常に理解しやすく、以下の手順が含まれています。

  1. Workbook インスタンスをファイルタイプに基づいて作成します。xlsx形式の場合は XSSFWorkbook、xls形式の場合は HSSFWorkbook を使用します。ファイル名に基づいてワークブックのインスタンスを取得するために、ファクトリーパターンを使用したラッパークラスを作成することもできることに注意してください。
  2. getNumberOfSheets() メソッドを使用してシートの数を取得し、その後、各シートを解析するために for ループを使用します。getSheetAt(int i) メソッドを使用して Sheet インスタンスを取得します。
  3. Row イテレーターを取得し、次に Cell イテレーターを取得して Cell オブジェクトを取得します。Apache POI はここで イテレーターパターンを使用しています。
  4. 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.journaldev.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 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 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());
		}
		
		//ここでExcelデータをファイルに書き込みましょう
		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 list = ReadExcelFileToList.readExcelData("Sample.xlsx");
		WriteListToExcelFile.writeCountryListToFile("Countries.xls", list);
	}
}

上記のApache POIの例プログラムを実行すると、生成されるExcelファイルは以下の画像のようになります。

Apache POIの例 – Excel数式の読み取り

時折、値とともにセルの複雑なExcelファイルを処理する必要があります。単純なApache POIの例を見て、セルの数式とその値を読み取る方法を見てみましょう。 ReadExcelFormula.java

package com.journaldev.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);
		
		//xlsxファイルを想定しています
		Workbook workbook = new XSSFWorkbook(fis);
		Sheet sheet = workbook.getSheetAt(0);
		Iterator rowIterator = sheet.iterator();
		while (rowIterator.hasNext()) 
        {
			Row row = rowIterator.next();
			Iterator 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.journaldev.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);
		//式のセルを設定
		row.createCell(3).setCellFormula("A1*B1*C1");
		
		//ファイルに書き込む
		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開発者ガイド

Source:
https://www.digitalocean.com/community/tutorials/apache-poi-tutorial