2011年4月15日金曜日

Apache POI(Java) でExcel その1(基本編)

Apache POI は, Java で Microsoft Office シリーズのファイル操作を扱う API です。
この中で, 今回 Excel を取り上げます。

POI の中で, Excel を扱うコンポーネントは, HSSF と XSSFで,それぞれ
Excel 2003と Excel2007以降の形式のサポートに分かれます

コンポーネント名     扱える形式            ライブラリ
HSSF                       .xls                           poi, commons-logging,  log4j
XSSF                       .xlsx                         poi-ooxml, poi-ooxml-schemas, dom4j, xmlbeans, geronimo-stax-api

利用するには, まず, Apache POI のページより  poiをダウンロードします。
http://poi.apache.org/

必要なライブラリは, すべて.zip や tar.gz に入っています。
Excel 2003 形式である .xls を扱うには,  poi の poi-xxx.jar,  libの中の commons-logging-xxx.jar, log4j-xx.jar  (xxx はバージョン)  を利用します

Excel2007 形式である .xlsx を扱うには, poi の  poi-ooxml-xxx.jar, poi-ooxml-schemas-xxx.jar
ooxml-lib の中の dom4j-xxx.jar, xmlbeans-xxx.jar, geronimo-stax-api-xxx.jar を利用します。



これで準備が整いました。

POI でExcel を扱うプログラムは,
忙しい人向けシリーズ
http://poi.apache.org/spreadsheet/quick-guide.html
が秀逸。 たいていのことはこれで十分です。
英語がどうしてもという方は, JavaDriveさんの記事などを参考にしては。
http://www.javadrive.jp/poi/

では, さっそくサンプルを動かしてみましょう。(一部省略)

1.  .xlsx のプログラム


Workbook wb = new HSSFWorkbook();

try
{
FileOutputStream fileOut = new FileOutputStream("workbook.xls");

// Create new sheet. name akb, ske
Sheet sheet1 = wb.createSheet("AKB");
Sheet sheet2 = wb.createSheet("SKE");

// Create cell and writes something.
// Add row number 0  start.
Row row = sheet1.createRow( 0 );
Cell A_0 = row.createCell( 0 );
A_0.setCellValue( "あつこ様" );

// Create cell ( sheet2 ).
Row row2 = sheet2.createRow( 0 );
Cell A_0_ske = row2.createCell( 0 );
A_0_ske.setCellValue( "玲奈" );

// Write contents of work book into file.
wb.write(fileOut);
fileOut.close();
}
catch ( IOException oops )
{
oops.printStackTrace();
}

これで, 実行フォルダに, workbook.xls ができました。(画像は OpenOffice)
プログラムの流れは,

Workbook オブジェクト(インターフェイスですが)  をつくり,
シートオブジェクトを作るそして,  各シートオブジェクトにRow オブジェクトをつくり,
行を扱う。 各行オブジェクトから, セルオブジェクトをつくり, セルオブジェクトに値を
入れ込む。
最後にWorkbook オブジェクトを, ファイルに書き込んで終了。

2. .xlxs



Workbook wb = new XSSFWorkbook();

try
{
FileOutputStream fileOut = new FileOutputStream("workbook2.xlsx");

// Create new sheet. name akb, ske
Sheet sheet1 = wb.createSheet("フレンチキス");
Sheet sheet2 = wb.createSheet("渡り廊下走り隊");

// Create cell and writes something.
// Add row number 0  start.
Row row = sheet1.createRow( 0 );
Cell A_0 = row.createCell( 0 );
A_0.setCellValue( "柏木ちゃん" );

// Create cell ( sheet2 ).
Row row2 = sheet2.createRow( 0 );
Cell A_0_ske = row2.createCell( 0 );
A_0_ske.setCellValue( "まゆゆ" );

// Write contents of work book into file.
wb.write(fileOut);
fileOut.close();
}
catch ( IOException oops )
{
oops.printStackTrace();
}


違うのは, XSSFWorkbook を使っているところのみ。

次にパフォーマンスについて考える

Workbook wb = new XSSFWorkbook();

try
{
FileOutputStream fileOut = new FileOutputStream("many.xlsx");

// Create new sheet. name Test
Sheet sheet1 = wb.createSheet("Test");

for ( int i=0; i < 100000; i++ )
{
Row row = sheet1.createRow( i );
Cell cell = row.createCell( 0 );
cell.setCellValue( i );
}

// Write contents of work book to file.
wb.write(fileOut);
fileOut.close();
}
catch ( IOException oops )
{
oops.printStackTrace();
}

このコードを利用して100000行のデータを書き込んでみる。



スペック
windows XP  メモリ2GB  Core2 Duo 約10000行で Out of Memory
windows 7   メモリ4GB  Core2 Quad 100000行で, なんか固まった感じでも動いた(180秒くらい)

という具合に, 大量データを書き込むと, WorkBookオブジェクトが肥大化し,メモリを
ものすごい勢いで食っていく。
このように, 大量データを書き込むことは向いていないと言わざるを得ない。

これを解決する術として, Java VM のメモリ容量を上げる方法などがネットでちらほら
ありますが, これではサーバ上で実行させるなど限られたリソースの元では苦しい。

そこで, 前回書いた OpenXML を利用した方法を利用しよう。
次回に続く。

0 件のコメント:

コメントを投稿