2009-05-25
■[Java][Seasar]S2Fisshplateで複数シートのテンプレート、シートごとに使うMapを分けたかったり(ry

ちゃんとDiffが取れれば良かったんですが、コードフォーマッタとか
あれとかの事情で上手く取れなかったし、Fisshplate同様大した量ではなかったので
S2Fisshplateの書き換えたソースをそのまま公開しちゃいます。(Apache License, Version 2.0)
元にしたソースは0.1.4スナップショットです。
以下の変更したソースと、前回のエントリの変更を加えたFisshplateを組み合わせて使う事で
1)複数シートのテンプレートに対して、対応する複数のDtoを渡す事が出来る様になる。
2)シート数に対して、渡されたDtoのListの方がsizeが大きい場合、自動でシートをクローンしてシート数を合わせてくれる。
3)2)の機能を利用したとき、Dtoの中に「sheetName」という名前のプロパティが存在した場合、そのDtoが埋め込まれるシート名をsheetNameに格納されている値に変更する。
という機能を追加で提供する事が可能です。
/* * Copyright 2004-2007 the Seasar Foundation and the Others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ package org.seasar.fisshplate.consts; /** * S2Fisshplate内で使用される定数です。 * @author rokugen */ public interface S2FPConsts { /** * テンプレート内でBeanを参照する変数名です。「data」になります。 */ static final String DATA_MAP_KEY_FOR_BEAN = "data"; /** * Excelファイルの拡張子です。 */ static final String EXCEL_EXTENSION = "xls"; /** * シート名を表すプロパティ名 */ static final String SHEET_NAME_PROPERTY = "sheetName"; }
/* * Copyright 2004-2007 the Seasar Foundation and the Others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ package org.seasar.fisshplate.util; import java.util.List; import java.util.Map; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.seasar.fisshplate.exception.FPMergeException; import org.seasar.fisshplate.exception.FPMergeRuntimeException; import org.seasar.fisshplate.exception.FPParseException; import org.seasar.fisshplate.exception.FPParseRuntimeException; import org.seasar.fisshplate.template.FPTemplate; /** * S2FisshplateのUtilクラスです。 * * @author rokugen * @author happy_ryo */ public class FisshplateUtil { private FisshplateUtil() { } /** * テンプレートにデータを埋め込みます。 * * @param workbook テンプレートオブジェクト * @param data 埋め込み用データ * @return 出力するワークブック */ public static final HSSFWorkbook process(HSSFWorkbook workbook, Map data) { try { FPTemplate template = new FPTemplate(); return template.process(workbook, data); } catch (FPMergeException e) { throw new FPMergeRuntimeException(e); } catch (FPParseException e) { throw new FPParseRuntimeException(e); } } /** * 複数のシートがあるテンプレートに、Listに格納されたMapからデータを埋め込みます。 * * @param workbook テンプレート * @param dataList 埋め込み用データ * @return 出力するワークブック */ public static final HSSFWorkbook process(HSSFWorkbook workbook, List dataList) { try { FPTemplate template = new FPTemplate(); return template.process(workbook, dataList); } catch (FPParseException ex) { throw new FPParseRuntimeException(ex); } catch (FPMergeException ex) { throw new FPMergeRuntimeException(ex); } } }
/* * Copyright 2004-2007 the Seasar Foundation and the Others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ package org.seasar.fisshplate.interceptor; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.aopalliance.intercept.MethodInvocation; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.seasar.fisshplate.consts.S2FPConsts; import org.seasar.fisshplate.meta.TemplateMetaData; import org.seasar.fisshplate.meta.TemplateMetaDataFactory; import org.seasar.fisshplate.util.FisshplateUtil; import org.seasar.framework.aop.interceptors.AbstractInterceptor; import org.seasar.framework.beans.BeanDesc; import org.seasar.framework.beans.PropertyDesc; import org.seasar.framework.beans.PropertyNotFoundRuntimeException; import org.seasar.framework.beans.factory.BeanDescFactory; import org.seasar.framework.util.MethodUtil; /** * S2Fisshplateを利用するためのインターセプタクラスです。 * * @author rokugen * @author happy_ryo * */ public class S2FisshplateInterceptor extends AbstractInterceptor { private TemplateMetaDataFactory metaDataFactory; private static final long serialVersionUID = -7692835504667883170L; /* * (non-Javadoc) * * @see * org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept * .MethodInvocation) */ public Object invoke(MethodInvocation invocation) throws Throwable { Method method = invocation.getMethod(); if (!MethodUtil.isAbstract(method)) { return invocation.proceed(); } Object[] arguments = invocation.getArguments(); if (arguments == null || arguments.length == 0) { return null; } Object bean = arguments[0]; Class clazz = method.getDeclaringClass(); TemplateMetaData metaData = metaDataFactory.getMetaData(clazz); HSSFWorkbook workbook = metaData.getWorkbook(method); if (bean instanceof List) { List dataList = new ArrayList(); List beanlist = (List) bean; if (beanlist.size() > workbook.getNumberOfSheets()) { cloneSheet(workbook, beanlist); } for (int i = 0; i < beanlist.size(); i++) { Map map = new HashMap(); map.put(S2FPConsts.DATA_MAP_KEY_FOR_BEAN, beanlist.get(i)); dataList.add(map); } return FisshplateUtil.process(workbook, dataList); } else { Map map = new HashMap(); map.put(S2FPConsts.DATA_MAP_KEY_FOR_BEAN, bean); return FisshplateUtil.process(workbook, map); } } private HSSFWorkbook cloneSheet(HSSFWorkbook workbook, List dataList) { final int workbookNumberOfSheets = workbook.getNumberOfSheets() - 1; final String defaultSheetName = workbook .getSheetName(workbookNumberOfSheets); for (int i = workbookNumberOfSheets; i < dataList.size(); i++) { if (dataList.size() > i && i != 0 && workbookNumberOfSheets != i) { workbook.cloneSheet(workbookNumberOfSheets); } BeanDesc bd = BeanDescFactory.getBeanDesc(dataList.get(i) .getClass()); try { PropertyDesc propertyDesc = bd .getPropertyDesc(S2FPConsts.SHEET_NAME_PROPERTY); workbook.setSheetName(i, (String) propertyDesc .getValue(dataList.get(i))); } catch (PropertyNotFoundRuntimeException ex) { if (workbookNumberOfSheets != i) { workbook.setSheetName(i, defaultSheetName + "_" + i); } } } return workbook; } /** * @param metaDataFactory */ public void setMetaDataFactory(TemplateMetaDataFactory metaDataFactory) { this.metaDataFactory = metaDataFactory; } }
変更するのは上記の3クラスのみです。
実際見るとわかりますが、とーーーっても小規模な変更です。
一応、こちらで既存のテストと、追加した機能のテストが通る事は確認しました。
これからも何か細かい変更とかしたらペタペタしようと思います。
トラックバック - http://d.hatena.ne.jp/happy_ryo/20090525

一つお伺いしたいのですが、
この改変は、本体には、取り込まれないんでしょうか?
使用したい機能なので、本体に取り込んでいただけると、
非常にありがたいなと思っています。
(関数埋め込みも含めて)
ご検討よろしくお願いします。