MY-NOTEBOOK

Friday, March 24, 2006

jakarta-POIを使ってエクセルデータを読む(Javaを使ってExcelデータを読み取る方法)

jakarta POI は、 MS-ExcelのデータをJavaから読みこみできるようにするライブラリです。

補足:Windows上で処理する場合の別の方法

ウインドウズ上で、Excelがインストールされたマシンでエクセルデータをプログラムで読みたい場合は、
Win32 OLEを経由するのが普通らしい。

Ruby,Perl,Pythonなどのサポートがよいようです。

本題:POI を使う利点

POI登場以前には、CSVデータ経由でエクセルからデータをJavaに渡すといった方法をとっていましたが、これは、スマートさに欠ます。
普段からテキストデータの扱いになれていない人にとっては、CSVを経由せずにエクセルデータから直接処理できるのは、非常に精神的負担が少ないようです。
また、日本語や多国語(中国語/ドイツ語/フランス語...)を含むデータをCSVを経由させた場合、文字エンコーディングに注意しないと思わぬ文字化けトラブルになりますが、POIを使う場合は、オペレーターに文字エンコーディングを意識させる必要はない、という利点があります。(客先担当者に文字エンコーディングの問題について説明する手間が省けるだけでもかなりのコストダウンかも・・・)

そもそも、処理したいデータがエクセルで管理されているとか、現在エクセルでやっているんだけど、もっと効率化したい、
という場合もありますので、POIは非常に役に立つツールです。

POIは、直感的で取り扱い易いAPIですが、表データをただJavaの配列に変換したいだけ、という単純作業で、毎回コードを書くのは面倒なので、使い回しが効くように、ラッパーを書いてみます。

エクセルデータをJavaの配列に変換するラッパー

一枚目のシートを対象に、エクセルシートをJava配列に変換します。
一レコード(一行)をString[]配列に変換したあと、それをArrayListに追加しています。
コードを見ての通り、A列からデータを入れていないとその行は処理されないつくりになっています。
(改造するのは簡単ですが、そのあたりのオプションを入れているとコードが長くなるので割愛)

XLSDataReader.java

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

public class XLSDataReader {
	
	static private String getValue(HSSFCell cell){
		String r="";
		try{
			r=cell.getStringCellValue();
		}
		catch(Exception ex){
			r=String.valueOf( cell.getNumericCellValue() );
		}
		return r;
	}

	static public ArrayList getData(File xlsfile){
		ArrayList list=new ArrayList();
		
		try{
			InputStream in=new FileInputStream(xlsfile);
			HSSFWorkbook book=new HSSFWorkbook(in);

			if(book.getNumberOfSheets()<1){
				return list;
			}
			
			//for(int i=0; i<book.getNumberOfSheets(); i++){
			{	
				//シートは一枚目のみを想定.
				HSSFSheet sheet=book.getSheetAt(0);
				
				int j=0;
				while(true){
					HSSFRow row=sheet.getRow(j);
					if(row==null){
						break;
					}
					j++;
					
					
					HSSFCell cell=row.getCell((short)0);
					if(cell!=null){
						String v=getValue(cell);
						if(v.length()>0){
							ArrayList cellList=new ArrayList();
							cellList.add(v);
	
							int lastCellNum=(int)row.getLastCellNum();
							for(int jj=1; jj<lastCellNum; jj++){
								HSSFCell cell2=row.getCell((short)jj);
								if(cell2==null){
									cellList.add("");
									//break;
								}
								else{
									cellList.add(getValue(cell2));
								}
							}
							
							list.add(cellList.toArray(new String[0]));
						}
					}
				}
			}

			in.close();
		}
		catch(Exception ex){
			ex.printStackTrace();
		}
		
		return list;
	}

}

制約事項

  • このプログラムは、一枚目のシートのみを対象に処理します。
  • A列からデータを入れておかないと意図通り作動しません。

XLSDataReader.javaを使うテスト用クラス

Test.java

import java.io.*;
import java.util.*;

public class Test {

	public static void main(String[] args) {

		if(args.length==1){
			File xlsf=new File(args[0]);
			ArrayList list=XLSDataReader.getData(xlsf);
		
			for(int i=0; i<list.size(); i++){
				String[] data=(String[])list.get(i);
				System.out.println(data);
			}
		}
	}
}

使い方

エクセル(またはOOOのCalc)でデータを作成して foo.xls という名前にして保存。
クラスパスに poi-3.0.1-FINAL-20070705.jar を通した上で、

$ java Test foo.xls
© 2006-2012 Tomoaki Oshima