現在、仕事で「Excella Reports」という、JavaからExcel/PDFを出力するライブラリを使用してます。
便利なのですが、中の人(?)も言っている通り、書式やスタイル設定はちょっと弱いところのようです。
なので、分かる範囲で書式・スタイル設定についてまとめてみました
ソースコード
import org.bbreak.excella.core.SheetData; import org.bbreak.excella.core.SheetParser; import org.bbreak.excella.core.exception.ParseException; import org.bbreak.excella.reports.listener.ReportProcessListener; import org.bbreak.excella.reports.model.ReportBook; import org.bbreak.excella.reports.model.ReportSheet; public class Main { public static void main(String[] args) throws Exception { // テンプレートファイルの指定 String templateFilePath = "SampleTemplate.xls"; String outputFileName = "Sample"; String outputFileDir = "Sample/Temp"; String outputFilePath = outputFileDir.concat(outputFileName); // ReportBookの作成 ReportBook outputBook = new ReportBook(templateFilePath, outputFilePath, ExcelExporter.FORMAT_TYPE); // シートの作成 ReportSheet outputSheet = new ReportSheet("TemplateSheet", "Sheet1"); outputBook.addReportSheet(outputSheet); // シートのセルに値を設定する。 int data = 1.23; outputSheet.addParam(SingleParamParser.DEFAULT_TAG, "DATA1", data1); // ReportProcessListenerの定義&ブックの出力 ReportProcessor reportProcessor = new ReportProcessor(); reportProcessor.addReportProcessListener(new SheetFormatSetter()); reportProcessor.process(outputBook); } }
import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.DataFormat; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.bbreak.excella.core.SheetData; import org.bbreak.excella.core.SheetParser; import org.bbreak.excella.core.exception.ParseException; import org.bbreak.excella.reports.listener.ReportProcessListener; import org.bbreak.excella.reports.model.ReportBook; import org.bbreak.excella.reports.model.ReportSheet; public class SheetFormatSetterimplements ReportProcessListener { public SheetFormatSetter() { } @Override public void postParse(Sheet sheet, SheetParser sheetParser, SheetData sheetData) throws ParseException { // WorkbookはsheetのgetWorkBook()メソッドから取得。 Workbook wb = sheet.getWorkBook(); CellStyle style = wb.createCellStyle(); // 表示形式、フォントの設定 DataFormat format = wb.createDataFormat(); style.setDataFormat(format.getFormat("#,##0.###"); Font font = wb.createFont(); font.setFontName("MS 明朝"); font.setFontHeightInPoints((short)10); style.setFont(font); // 縦横位置&上枠線の設定 style.setAlignment(Cellstyle.ALIGN_RIGHT); style.setVerticalAlignment(Cellstyle.VERTICAL_CENTER); style.setBorderTop(CellStyle.BORDER_THICK); // 対象セル(A1)を取得し、スタイルを設定 Row row = sheet.getRow(0); Cell cell = row.getCell(0); cell.setCellStyle(style); return; } }
基本的にはリファレンスにも書いてある通り、ReportProcessListenerのメソッド(preXX(), postXX())から、Apache POIのAPIを直接呼び出すことになります。
ブック&スタイルの作成
Workbook wb = sheet.getWorkBook(); CellStyle style = wb.createCellStyle();
Apache POIだと、CellStyleをHSSFWorkBookクラスのcreateCellStyle()メソッドで作成しますが、Excella ReportsのReportBookクラスには、それに該当するメソッドはありません。
ただし、ReportProcessListenerのメソッドの引数sheetのgetWorkBook()メソッドでWorkBookが取得できますので、そのcreateCellStyle()メソッドからCellStyleを取得できます。
スタイルの各書式の設定
// 上から順に、位置揃え(横)、位置揃え(縦)、セルの上枠線
style.setAlignment(Cellstyle.ALIGN_RIGHT);
style.setVerticalAlignment(Cellstyle.VERTICAL_CENTER);
style.setBorderTop(CellStyle.BORDER_THICK);
スタイルの各プロパティの設定は、プロパティごとに設定用のメソッドが用意されているので、それを使用します。
上記のように、あらかじめ用意されている定数をそのまま使用する場合は、該当の定数を引数に指定します。
// 表示形式、およびフォント DataFormat format = wb.createDataFormat(); style.setDataFormat(format.getFormat("#,##0.###"); Font font = wb.createFont(); font.setFontName("MS 明朝"); font.setFontHeightInPoints((short)10); style.setFont(font);
定数をそのまま使用するのではなく、自分で色々カスタマイズする場合、上記のようにWorkBookのcreateXX()メソッドで該当のインターフェースを取得後、
そのsetXX()メソッドで各種プロパティを設定し、最後にCellStyleの設定用メソッドの引数として該当のインターフェースのインスタンスを渡します。
実際にセルに設定する
Row row = sheet.getRow(0); Cell cell = row.getCell(0); cell.setCellStyle(style);
最後に、SheetのgetRow()メソッド、及びRowのgetCell()メソッドで対象のセルを取得し、そのsetCellStyle()メソッドの引数に先程のCellStyleのインスタンスを渡し、実際に書式・スタイルを適用します。
なお、長くなるので省略していますが、実際にはrowやcellのnullチェックを忘れないようにしてください。(値が設定されていない場合、nullが返ります。)
また、今回は値を決め打ちしたので不要でしたが、実際に表示形式など、値の内容に依存する書式を設定する際は、事前にCellのgetCellType()メソッドで、セルの値の型を調べるのを忘れないようにしてください。
参考サイト
前回の投稿から2ヶ月...確かに新年入ってから、すごくメンタルの調子が悪かったのです。
...でも、もう少し更新頻度は上げていきたいです。