package com.gh.mygreen.xlsmapper; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import com.gh.mygreen.xlsmapper.annotation.OverRecordOperate; import com.gh.mygreen.xlsmapper.annotation.XlsColumn; import com.gh.mygreen.xlsmapper.annotation.XlsDateConverter; import com.gh.mygreen.xlsmapper.annotation.XlsHorizontalRecords; import com.gh.mygreen.xlsmapper.annotation.XlsLabelledCell; import com.gh.mygreen.xlsmapper.annotation.XlsSheet; import com.gh.mygreen.xlsmapper.validation.SheetBindingErrors; /** * ExcelのシートとJavaオブジェクトをマッピングする機能を提供する。 * * <h3 class="description">マッピングの基本</h3> * <p>次のような表のExcelシートをマッピングする例を説明します。</p> * * <div class="picture"> * <img src="doc-files/howto_load.png"> * <p>基本的なマッピング</p> * </div> * * <p>まず、シート1つに対して、POJOクラスを作成します。</p> * <ul> * <li>シート名を指定するために、アノテーション {@link XlsSheet} をクラスに付与します。</li> * <li>見出し付きのセル「Date」をマッピングするフィールドに、アノテーション {@link XlsLabelledCell} に付与します。</li> * <li>表「User List」をマッピングするListのフィールドに、アノテーション {@link XlsHorizontalRecords} を付与します。</li> * </ul> * * * <pre class="highlight"><code class="java"> * // シート用のPOJOクラスの定義 * {@literal @XlsSheet(name="List")} * public class UserSheet { * * {@literal @XlsLabelledCell(label="Date", type=LabelledCellType.Right)} * Date createDate; * * {@literal @XlsHorizontalRecords(tableLabel="User List")} * {@literal List<UserRecord>} users; * * } * </code></pre> * * * <p>続いて、表「User List」の1レコードをマッピングするための、POJOクラスを作成します。</p> * <ul> * <li>レコードの列をマッピングするために、アノテーション {@link XlsColumn} をフィールドに付与します。</li> * <li>フィールドのクラスタイプが、intや列挙型の場合もマッピングできます。</li> * </ul> * * <pre class="highlight"><code class="java"> * // レコード用のPOJOクラスの定義 * public class UserRecord { * * {@literal @XlsColumn(columnName="ID")} * int no; * * {@literal @XlsColumn(columnName="Class", merged=true)} * String className; * * {@literal @XlsColumn(columnName="Name")} * String name; * * {@literal @XlsColumn(columnName="Gender")} * Gender gender; * * } * * // 性別を表す列挙型の定義 * public enum Gender { * male, female; * } * </code></pre> * * * <p>作成したPOJOを使ってシートを読み込むときは、XlsMapper#load メソッドを利用します。</p> * * <pre class="highlight"><code class="java"> * // シートの読み込み * XlsMapper xlsMapper = new XlsMapper(); * UserSheet sheet = xlsMapper.load( * new FileInputStream("example.xls"), // 読み込むExcelファイル。 * UserSheet.class // シートマッピング用のPOJOクラス。 * ); * </code></pre> * * * <h3 class="description">書き込み方の基本</h3> * <p>同じシートの形式を使って、書き込み方を説明します。 * <br>まず、書き込み先のテンプレートとなるExcelシートを用意します。 レコードなどは空を設定します。 * </p> * * <div class="picture"> * <img src="doc-files/howto_save.png"> * <p>データが空のテンプレートファイル</p> * </div> * * <p>続いて、読み込み時に作成したシート用のマッピングクラスに、書き込み時の設定を付け加えるために修正します。</p> * <ul> * <li>セル「Date」の書き込み時の書式を指定するために、アノテーション {@link XlsDateConverter} に付与します。 * <br>属性 {@link XlsDateConverter#excelPattern()} でExcelのセルの書式を設定します。 * </li> * <li>表「User List」のレコードを追加する操作を指定するために、アノテーションの属性 {@link XlsHorizontalRecords#overRecord()}を指定します。 * <br>テンプレート上は、レコードが1行分しかないですが、実際に書き込むレコード数が2つ以上の場合、足りなくなるため、その際のシートの操作方法を指定します。 * <br>今回の{@link OverRecordOperate#Insert}は、行の挿入を行います。 * </li> * </ul> * * <pre class="highlight"><code class="java"> * // シート用のPOJOクラスの定義 * {@literal @XlsSheet(name="List")} * public class UserSheet { * * {@literal @XlsLabelledCell(label="Date", type=LabelledCellType.Right)} * {@literal @XlsDateConverter(excelPattern="yyyy/m/d")} * Date createDate; * * {@literal @XlsHorizontalRecords(tableLabel="User List", overRecord=OverRecordOperate.Insert)} * {@literal List<UserRecord>} users; * * } * </code></pre> * * <p>修正したPOJOを使ってシートを書き込むときは、 XlsMapper#save メソッドを利用します。</p> * * <pre class="highlight"><code class="java"> * // 書き込むシート情報の作成 * UserSheet sheet = new UserSheet(); * sheet.createDate = new Date(); * * {@literal List<UserRecord>} users = new {@literal ArrayList<>}(); * * // 1レコード分の作成 * UserRecord record1 = new UserRecord(); * record1.no = 1; * record1.className = "A"; * record1.name = "Ichiro"; * record1.gender = Gender.male; * users.add(record1); * * UserRecord record2 = new UserRecord(); * // ... 省略 * users.add(record2); * * sheet.users = users; * * // シートの書き込み * XlsMapper xlsMapper = new XlsMapper(); * xlsMapper.save( * new FileInputStream("template.xls"), // テンプレートのExcelファイル * new FileOutputStream("out.xls"), // 書き込むExcelファイル * sheet // 作成したデータ * ); * </code></pre> * * @author T.TSUCHIE * */ public class XlsMapper { private XlsMapperConfig config; private XlsLoader loader; private XlsSaver saver; public XlsMapper() { this.config = new XlsMapperConfig(); this.loader = new XlsLoader(getConig()); this.saver = new XlsSaver(getConig()); } public XlsMapperConfig getConig() { return config; } public void setConig(XlsMapperConfig config) { this.config = config; getLoader().setConfig(config); getSaver().setConfig(config); } public XlsLoader getLoader() { return loader; } public XlsSaver getSaver() { return saver; } /** * Excelファイルの1シートを読み込み、任意のクラスにマッピングする。 * @param xlsIn 読み込みもとのExcelファイルのストリーム。 * @param clazz マッピング先のクラスタイプ。 * @return * @throws XlsMapperException * @throws IOException * @throws IllegalArgumentException xlsIn == null. * @throws IllegalArgumentException clazz == null. * */ public <P> P load(final InputStream xlsIn, final Class<P> clazz) throws XlsMapperException, IOException { return loader.load(xlsIn, clazz); } /** * Excelファイルの1シートを読み込み、任意のクラスにマッピングする。 * @param xlsIn 読み込みもとのExcelファイルのストリーム。 * @param clazz マッピング先のクラスタイプ。 * @param xmlIn XMLによる定義を必要としない場合は、nullを指定する。 * @return * @throws XlsMapperException * @throws IOException * @throws IllegalArgumentException xlsIn == null. * @throws IllegalArgumentException clazz == null. */ public <P> P load(final InputStream xlsIn, final Class<P> clazz, final InputStream xmlIn) throws XlsMapperException, IOException { return loader.load(xlsIn, clazz, xmlIn); } /** * Excelファイルの1シートを読み込み、任意のクラスにマッピングする。 * @param xlsIn 読み込みもとのExcelファイルのストリーム。 * @param clazz マッピング先のクラスタイプ。 * @return * @throws XlsMapperException * @throws IOException * @throws IllegalArgumentException xlsIn == null. * @throws IllegalArgumentException clazz == null. * */ public <P> P load(final InputStream xlsIn, final Class<P> clazz, final SheetBindingErrors errors) throws XlsMapperException, IOException { return loader.load(xlsIn, clazz, errors); } /** * Excelファイルの1シートを読み込み、任意のクラスにマッピングする。 * @param xlsIn 読み込みもとのExcelファイルのストリーム。 * @param clazz マッピング先のクラスタイプ。 * @param xmlIn XMLによる定義を必要としない場合は、nullを指定する。 * @param errors マッピング時のエラー情報。指定しない場合は、nulを指定する。 * @return * @throws XlsMapperException * @throws IOException * @throws IllegalArgumentException xlsIn == null. * @throws IllegalArgumentException clazz == null. */ public <P> P load(final InputStream xlsIn, final Class<P> clazz, final InputStream xmlIn, final SheetBindingErrors errors) throws XlsMapperException, IOException { return loader.load(xlsIn, clazz, xmlIn, errors); } /** * Excelファイルの複数シートを読み込み、任意のクラスにマップする。 * @param xlsIn * @param clazz * @return * @throws XlsMapperException * @throws IOException */ public <P> P[] loadMultiple(final InputStream xlsIn, final Class<P> clazz) throws XlsMapperException, IOException { return loader.loadMultiple(xlsIn, clazz); } /** * XMLによるマッピングを指定し、Excelファイルの複数シートを読み込み、任意のクラスにマップする。 * @param xlsIn * @param clazz * @param xmlIn * @return * @throws XlsMapperException * @throws IOException */ public <P> P[] loadMultiple(final InputStream xlsIn, final Class<P> clazz, final InputStream xmlIn) throws XlsMapperException, IOException { return loader.loadMultiple(xlsIn, clazz, xmlIn); } /** * XMLによるマッピングを指定し、Excelファイルの複数シートを読み込み、任意のクラスにマップする。 * @param xlsIn * @param clazz * @param errorsContainer * @return * @throws XlsMapperException * @throws IOException */ public <P> P[] loadMultiple(final InputStream xlsIn, final Class<P> clazz, final SheetBindingErrorsContainer errorsContainer) throws XlsMapperException, IOException { return loader.loadMultiple(xlsIn, clazz, errorsContainer); } /** * XMLによるマッピングを指定し、Excelファイルの複数シートを読み込み、任意のクラスにマップする。 * @param xlsIn * @param clazz * @param xmlIn * @param errorsContainer * @return * @throws XlsMapperException * @throws IOException */ public <P> P[] loadMultiple(final InputStream xlsIn, final Class<P> clazz, final InputStream xmlIn, SheetBindingErrorsContainer errorsContainer) throws XlsMapperException, IOException { return loader.loadMultiple(xlsIn, clazz, xmlIn, errorsContainer); } public Object[] loadMultiple(final InputStream xlsIn, final Class<?>[] classes) throws XlsMapperException { return loader.loadMultiple(xlsIn, classes); } public Object[] loadMultiple(final InputStream xlsIn, final Class<?>[] classes, final InputStream xmlIn) throws XlsMapperException { return loader.loadMultiple(xlsIn, classes, xmlIn); } public Object[] loadMultiple(final InputStream xlsIn, final Class<?>[] classes, final SheetBindingErrorsContainer errorsContainer) throws XlsMapperException { return loader.loadMultiple(xlsIn, classes, errorsContainer); } public Object[] loadMultiple(final InputStream xlsIn, final Class<?>[] classes, final InputStream xmlIn, final SheetBindingErrorsContainer errorsContainer) throws XlsMapperException { return loader.loadMultiple(xlsIn, classes, xmlIn, errorsContainer); } /** * JavaのオブジェクトをExeclファイルに出力する。 * <p>出力するファイルは、引数で指定した雛形となるテンプレート用のExcelファイルをもとに出力する。 * @param templateXlsIn 雛形となるExcelファイルの * @param xlsOut 出力 * @param beansObj 書き込み元のオブジェクト * @throws XlsMapperException * @throws IOException */ public void save(final InputStream templateXlsIn, final OutputStream xlsOut, final Object beansObj) throws XlsMapperException, IOException { saver.save(templateXlsIn, xlsOut, beansObj); } /** * XMLによるマッピングを指定して、JavaのオブジェクトをExcelファイルに出力する。 * @param templateXlsIn * @param xlsOut * @param beansObj * @param xmlIn * @throws XlsMapperException * @throws IOException */ public void save(final InputStream templateXlsIn, final OutputStream xlsOut, final Object beansObj, final InputStream xmlIn) throws XlsMapperException, IOException { saver.save(templateXlsIn, xlsOut, beansObj, xmlIn); } /** * 複数のオブジェクトをそれぞれのシートへ保存する。 * @param templateXlsIn 雛形となるExcelファイルの入力 * @param xlsOut 出力 * @param beanObjs 書き込むオブジェクトの配列。 * @throws XlsMapperException * @throws IOException */ public void saveMultiple(final InputStream templateXlsIn, final OutputStream xlsOut, final Object[] beanObjs) throws XlsMapperException, IOException { saver.saveMultiple(templateXlsIn, xlsOut, beanObjs); } /** * 複数のオブジェクトをそれぞれのシートへ保存する。 * @param templateXlsIn 雛形となるExcelファイルの入力 * @param xlsOut 出力 * @param beanObjs 書き込むオブジェクトの配列。 * @param xmlIn アノテーションの定義をしているXMLファイルの入力。 * @throws XlsMapperException * @throws IOException */ public void saveMultiple(final InputStream templateXlsIn, final OutputStream xlsOut, final Object[] beanObjs, final InputStream xmlIn) throws XlsMapperException, IOException { saver.saveMultiple(templateXlsIn, xlsOut, beanObjs, xmlIn); } }