再び、スタイルについて
先ほどの簡単なスプレッドシートの作成方法を利用すれば、大抵のWebアプリケーションでユーザーにスプレッドシートを提供できます。しかし、これでは不十分な場合もあります。例えば、未使用のセルがブランクになっていないことを細かく指摘するユーザーがいるかもしれません。その程度のことなら新しいAPIを学習しようと発奮する開発者はあまりいないでしょうが、もっと切実な状況として、アプリケーションで数式や複数のシートを提供することが必要な場合があります。どちらの場合も、Apache POI HSSFライブラリが助けになります。
ここでは、2つのワークシートを含むブックを作成していきます。HSSFライブラリは範囲が広く、ここで取り上げるのはいくつかの基本機能だけです。詳細については、きちんとしたJavaDocを参照してください。
設計を簡単にするため、特定のスプレッドシートまたはスプレッドシートの種類には特定のクラスを使うことをお勧めします。例えば、データモデルおよびブックの出力はアプリケーションに必要な程度に単純または複雑であるものとして、時間短縮のために警告をいくつか定義します。
最低限の作業で例を作成できるように、まったく同じワークシートを2つ作成します。ブック内のワークシートはどのようなものでもかまいません。この例では、いくつかの基本的な株価分析値を使用します。簡単なBeanが各行のデータを保持し、Writerクラスはこのデータのみに対する固有のものなので、ヘッダーの値はWriterクラスにハードコーディングできます。パラメータとして受け取ったり、リフレクションを使って動的に作成したりする必要はありません。株価のBeanをCollectionにバンドルすることで簡単に使用できます。
データを定義すると、Writerクラスが基本的なHSSFコンポーネントを使用して最終的なExcelスプレッドシートを作成します。
HSSFWorkbook excelWorkbook = new HSSFWorkbook(); HSSFSheet excelSheet = null; HSSFRow sheetRow = null; HSSFCell rowCell = null;
HSSFCellStyleオブジェクトではスプレッドシートのスタイルが定義されています。APIを見てみると、各HSSFCellオブジェクトにHSSFCellStyleを使用すると、スプレッドシートのスタイルを簡単に設定できるように見えます。実際の実装では、スプレッドシートが大きくなるとこの方法には問題があり、完成したスプレッドシートに含まれるExcel表示用の定義があまりにも多くなることがあります。HSSFCellStyleを使うときは、使用するスタイルごとに1つのHSSFCellStyleオブジェクトを作成し、それを適切なHSSFCellオブジェクトに適用するようにします。従って、特定のWriterクラスに加えて、スプレッドシートの種類に対して使用するスタイルのコレクションを保持するための専用のオブジェクトを用意すると便利な場合があります。スプレッドシートで使用するスタイルの数が限られている場合は、1つのオブジェクトを共有するのでもかまいません。ごく基本的なスタイルオブジェクトは次のようになります。
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
public class SimpleStyleExample
{
private static HSSFCellStyle headerStyle;
public SimpleStyleExample(HSSFWorkbook excelWorkBook)
{
this.excelWorkBook = excelWorkBook;
headerStyle = this.excelWorkBook.createCellStyle();
this.headerStyle.setFont(headerFont);
this.headerStyle.setFillPattern(headerStyle.SOLID_FOREGROUND);
this.headerStyle.setBorderBottom(headerStyle.BORDER_THIN);
this.headerStyle.setBorderLeft(headerStyle.BORDER_THIN);
this.headerStyle.setBorderRight(headerStyle.BORDER_THIN);
this.headerStyle.setBorderTop(headerStyle.BORDER_THIN);
this.headerStyle.setBottomBorderColor(HSSFColor.WHITE.index);
this.headerStyle.setLeftBorderColor(HSSFColor.WHITE.index);
this.headerStyle.setRightBorderColor(HSSFColor.WHITE.index);
this.headerStyle.setTopBorderColor(HSSFColor.WHITE.index);
}
public HSSFCellStyle getHeaderStyle()
{
return headerStyle;
}
この例で定義されているスタイルは1つだけですが、実際の実装では、特定のスプレッドシートまたはスプレッドシートの種類で使用するすべてのスタイルと共に、すべての具体的なデータ書式、フォント、およびパレットを定義することになります。スタイルを静的にすることで、最終的なスプレッドシート内で作成されるスタイルオブジェクトが多くなりすぎて、Excelへの読み込みが困難になったり、大きなデータセットでは実行できなくなったりすることを防ぎます。
シートの完成
最後に、StyleクラスをWriterクラスに追加し、getが何回も呼び出されるのを防ぐためにスタイルをローカルにマップします。
ExcelWriterDemoStyles styles = new ExcelWriterDemoStyles(excelWorkbook); HSSFCellStyle headerStyle = styles.getHeaderStyle(); HSSFDataFormat dataFormat = styles.getDataFormat(); HSSFFont headerFont = styles.getHeaderFont(); HSSFPalette palette = styles.getPalette();
次に、Excel内でワークシートを作成するのと同じように、最初のシートを作成し、列の幅を設定し、最初の行にヘッダーの値を格納します。
excelSheet = excelWorkbook.createSheet("Today Stock Analysis");
sheetRow = excelSheet.createRow(0);
excelSheet.setColumnWidth(0, 6000);
excelSheet.setColumnWidth(1, 6000);
excelSheet.setColumnWidth(2, 2500);
excelSheet.setColumnWidth(3, 2500);
excelSheet.setColumnWidth(4, 3000);
sheetRow.setHeight((short)600);
for(int cellIndex = 0; cellIndex < HEADINGS.length; cellIndex++)
{
rowCell = sheetRow.createCell(cellIndex);
rowCell.setCellType(HSSFCell.CELL_TYPE_STRING);
rowCell.setCellValue(new
HSSFRichTextString(HEADINGS[cellIndex]));
rowCell.setCellStyle(headerStyle);
}
次に、行ごとに各列のデータを追加します。
for(Iterator<ExcelWriterDemoStock> stockIt =
data[0].getDemoDataCollection().iterator();
stockIt.hasNext(); rowIndex++)
{
sheetRow = excelSheet.createRow(rowIndex);
stock = stockIt.next();
rowCell = sheetRow.createCell(0);
rowCell.setCellType(HSSFCell.CELL_TYPE_STRING);
rowCell.setCellStyle(styles.getDataStringStyle());
rowCell.setCellValue(new
HSSFRichTextString(stock.getSymbol()));
rowCell = sheetRow.createCell(1);
rowCell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
rowCell.setCellStyle(styles.getDataDollarStyle());
rowCell.setCellValue(stock.getPrice());
rowCell = sheetRow.createCell(2);
rowCell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
rowCell.setCellValue(stock.getPeg());
rowCell = sheetRow.createCell(3);
rowCell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
rowCell.setCellValue(stock.getYield());
rowCell = sheetRow.createCell(4);
rowCell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
rowCell.setCellValue(stock.getChange());
}
ブックに含まれるワークシートごとに必要なだけ繰り返します。
ブックが完成したら、「簡単なスプレッドシート」のときと同じように、XLS MIMEタイプとしてストリーミングします。
<%@ page import="com.fywservices.poi.hssf.*"%>
<%@ page import="org.apache.poi.hssf.usermodel.*" %>
<%
ExcelWriterDemoData[] demoData = new ExcelWriterDemoData[]{
new ExcelWriterDemoData(),
new ExcelWriterDemoData()};
ExcelWriterDemo demo = new ExcelWriterDemo();
HSSFWorkbook excelWorkbook =
demo.createExcelWorkbook(demoData);
response.reset();
response.setContentType("application/xls");
response.setHeader("Content-Disposition",
"attachment;filename=StockDemo.xls");
excelWorkbook.write(response.getOutputStream());
%>
最終的に表示される複数シートのスタイル付きブックは次のようになります。

