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の重要なポイントは以下の通りです。

    1. Apache POIには、Excel ’97(-2007)のファイル形式であるXLSのHSSF実装が含まれています。

 

    1. Excel 2007のOOXML (.xlsx)ファイル形式には、Apache POIのXSSF実装を使用する必要があります。

 

    1. Apache POIのHSSFとXSSF APIは、Excelスプレッドシートを読み取ったり、書き込んだり、変更したりするための仕組みを提供します。

 

    1. Apache POIはSXSSF APIも提供しており、非常に大きなExcelシートを扱うためのXSSFの拡張です。SXSSF APIはメモリを少なく使用し、ヒープメモリが制限されている場合に適しています。

 

    1. 選択できるモデルは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);
	}

}

このプログラムは非常に理解しやすく、以下のステップを含んでいます。

    1. ファイルの種類に基づいてWorkbookインスタンスを作成します。xlsx形式の場合はXSSFWorkbookを使用し、xls形式の場合はHSSFWorkbookを使用してください。なお、ファイル名を基にWorkbookインスタンスを取得するために、ファクトリーパターンを使用したラッパークラスを作成することもできます。

 

    1. getNumberOfSheets()メソッドを使用してシートの数を取得し、それぞれのシートを解析するためにforループを使用してください。getSheetAt(int i)メソッドを使用してSheetインスタンスを取得します。

 

    1. 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開発者ガイド。

コメントを残す 0

Your email address will not be published. Required fields are marked *