XLSBeansはアノテーションを付与してJavaBeansとExcelをマッピングするライブラリ(プロトタイプ)です。 以下のアノテーションが利用可能です。
読み込むシートをシート番号、シート名、シート名に対する正規表現のいずれかで指定します。クラスに付与します。
/** シート番号で指定する場合 */ @Sheet(number=0) public class SheetObject { ... }
/** シート名で指定する場合 */ @Sheet(name="Users") public class SheetObject { ... }
/** 正規表現で指定する場合 */ @Sheet(regex="Sheet_[0-9]+") public class SheetObject { ... }
正規表現で指定する場合はXLSBeans#loadMultiple()
メソッドを用いることでマッチしたシートの情報を一度に取得することができます。
セルの列、行を指定してBeanのプロパティにマッピングします。setterメソッドに対して付与します。
@Sheet(name="Users") public class SheetObject { @Cell(column=0, row=0) public void setTitle(String title){ ... } }
セルの文字列を指定し、その左右もしくは下側のセルの値をマッピングします。setterメソッドに対して付与します。
@Sheet(name="Users") public class SheetObject { @LabelledCell(label="Title", type=LabelledCellType.Right) public void setTitle(String title){ ... } }
range
パラメータを指定すると、type
パラメータの方向に向かって指定したセル数分を検索し、
最初に発見した空白以外のセルの値を取得します。
@Sheet(name="Users") public class SheetObject { @LabelledCell(label="Title", type=LabelledCellType.Right, range=3) public void setTitle(String title){ ... } }
同じラベルのセルが複数ある場合は、領域の見出しをheaderLabel
パラメータで指定します。
headerLabel
パラメータで指定されたセルからlabel
パラメータで指定されたセルを下方向に検索し、
最初に見つかったセルをラベルセルとして使用します。
@LabelledCell(label="クラス名", type=LabelledCellType.Right, headerLabel="アクション") public void setActionClassName(String actionClassName){ ... } @LabelledCell(label="クラス名", type=LabelledCellType.Right, headerLabel="アクションフォーム") public void setFormClassName(String formClassName){ ... }
セルが見つからなかった場合はエラーとなりますが、optional
パラメータに
true
を指定しておくと、無視して処理を続行します。
シート名をString
型のプロパティにマッピングします。
@Sheet(name="Users") public class SheetObject { @SheetName public void setSheetName(String sheetName){ ... } }
水平方向に連続する行をList
または配列にマッピングします。
表には最上部にテーブルの名称と列名を記述した行が必要になります。
tableLabel
パラメータでテーブルの名称を指定します。
List
型または配列の引数を1つだけ取るsetterメソッドに対して付与します。
@Sheet(name="Users") public class SheetObject { @HorizontalRecords(tableLabel="ユーザ一覧", recordClass=Record.class) public void setRecords(List<Record> records){ ... } }
デフォルトでは行に1つもデータが存在しない場合、そのテーブルの終端となります。
行の一番左側の列のボーダーによってテーブルの終端を検出する方法もあります。
この場合は@HorizontalRecords
のterminal
パラメータに
RecordTerminal.Border
を指定してください。
@Sheet(name="Users") public class SheetObject { @HorizontalRecords(tableLabel="Horizontal Records", recordClass=Record.class, terminal=RecordTerminal.Border) public void setRecords(List<Record> records){ ... } }
テーブルが他のテーブルと連続しておりterminal
パラメータでBorder
、
Empty
のいずれを指定しても終端を検出できない場合があります。
このような場合はterminateLabel
パラメータで終端を示すセルの文字列を指定します。
@Sheet(name="Users") public class SheetObject { @HorizontalRecords(tableLabel="Horizontal Records", recordClass=Record.class, terminateLabel="Terminate") public void setRecords(List<Record> records){ ... } }
セルが見つからなかった場合はエラーとなりますが、optional
パラメータに
true
を指定しておくと、無視して処理を続行します。
垂直方向に連続する列をList
または配列にマッピングします。
要するに@HorizontalRecords
を縦方向にしたものです。
@HorizontalRecords
と同じくList
型の引数を1つだけ取るsetterメソッドに対して付与します。
@Sheet(name="Users") public class SheetObject { @VerticalRecords(tableLabel="Vertical Records", recordClass=Record.class) public void setRecords(List<Record> records){ ... } }
@HorizontalRecords
と同じくterminal
パラメータ、
およびoptional
パラメータを指定することもできます。
@HorizontalRecords
または@VerticalRecords
で指定されたクラスのプロパティをカラム名にマッピングします。
setterメソッドに対して付与します。
public class Record { @Column(columnName="ID") public void setId(String id){ ... } }
同じ値がグループごとに結合されているカラムの場合はmerged
パラメータをtrue
に設定します。
こうしておくと、前の列の値が引き継がれて設定されます。
public class Record { @Column(columnName="Gender", merged=true) public void setId(String id){ ... } }
見出し行が結合され、1つの見出しに対して複数の列が存在する場合はheaderMerged
プロパティを使用します。
headerMerged
の値には列見出しから何セル分離れているかを指定します。
public class User { @Column(columnName="連絡先") public void setMailAddress(String mailAddress){ ... } @Column(columnName="連絡先", headerMerged=1) public void setTel(String tel){ ... } }
@HorozintalRecord
もしくは@VerticalRecord
でカラム数が可変の場合に、
それらのカラムをMap
として設定します。BeanにはMap
を引数に取る
セッターメソッドを用意し、このアノテーションを記述します。
@MapColumns(previousColumnName="名前") public void setAttributes(Map attributes){ this.attributes = attributes }
previousColumnName
パラメータで指定された次のカラム以降、カラム名をキーとした
Map
が生成され、Beanにセットされます。
@Sheet
を付与したクラス、もしくは@HorizontalRecords
や@VerticalRecords
で指定したレコードクラスのメソッドに付与しておくと、シートの読み込みが終了した時点で呼び出されます。
なお、このアノテーションを付与するメソッドは引数を取らないpublicメソッドである必要があります。
@Sheet(name="Users") public class SheetObject { @PostProcess public void postProcess(){ ... } }
同一の構造の表がシート内で繰り返し出現する場合に使用します。
tableLabel
プロパティで繰り返し部分の見出しラベル、
tableClass
プロパティで繰り返し部分の情報を格納するJavaBeanを指定します。
また、bottom
プロパティは@IterateTables
内で
@HorizontalRecord
を使用する場合に、
テーブルの開始位置が@IterateTables
の見出しセルからどれだけ離れているかを指定します。
@Sheet(name="シート名") public class SheetObject { @IterateTables(tableLabel="部門情報", tableClass=Unit.class, bottom=2) public void setUnits(List<Unit> units){ ... } }
繰り返し部分に対応するJavaBeanでは以下のように@LabelledCell
や
@HorizontalRecord
などのアノテーションを使用することができます。
@HorizontalRecord
を使用する場合、tableLabel
プロパティには
@IterateTables
のtableLabel
プロパティで指定したラベルと
同じラベルを指定する必要がある点に注意してください。
public class Unit { @LabelledCell(label="部門名", type=LabelledCellType.Right) public void setUnitName(String unitName) { ... } @HorizontalRecords(tableLabel="部門情報", recordClass=UnitUser.class) public void setUnitUsers(List<UnitUser> unitUsers) { this.unitUsers = unitUsers; } }
繰り返し部分に対応するJavaBeanで@HorizontalRecord
を使用した場合、
通常の場合と同じく@Column
で列とのマッピングを行います。
public class UnitUser { @Column(columnName="ID") public void setId(String id) { ... } @Column(columnName="名前") public void setName(String name) { ... } }
以下のようにして読み込みを行います。
SheetObject sheet = new XLSBeans.load( new FileInputStream("example.xls"), SheetObject.class);
なお、@Cell
, @LabelledCell
, @Column
アノテーションで
マッピングするプロパティに関しては、現時点ではString
型、プリミティブ型、プリミティブ型の
ラッパー型のいずれかである必要があります。より具体的な使用例はexampleフォルダ内のソースコードをご覧ください。
アノテーションを付与したsetterメソッド名+Positionというメソッドを用意しておくと、 マッピングされたセル上の位置を取得することができます。
@LabelledCell(label="Name") public void setName(String name){ ... } public void setNamePosition(int x, int y){ ... }
位置情報を取得用のsetterメソッドは以下のいずれかの引数を取る必要があります。
アノテーションだけではなく、外部XMLファイルでマッピングを行うことも可能です。 これはダイナミック・アノテーションという、アノテーションと同様の情報をXMLファイルで定義することで行います。 以下にクラスに対してアノテーションを付与するXMLファイルの例を示します。
<?xml version="1.0" encoding="utf-8"?> <annotations> <class name="net.java.amateras.xlsbeans.example.SheetObject"> <annotation name="net.java.amateras.xlsbeans.annotation.Sheet"> <attribute name="name">'Users'</attribute> </annotation> </class> </annotations>
アノテーションの属性値の指定にはOGNL式を使用します。メソッドにアノテーションを付与する場合は次のようになります。
<?xml version="1.0" encoding="utf-8"?> <annotations> <class name="net.java.amateras.xlsbeans.example.SheetObject"> <annotation name="net.java.amateras.xlsbeans.annotation.Sheet"> <attribute name="name">'Users'</attribute> </annotation> <method name="setTitle"> <annotation name="net.java.amateras.xlsbeans.annotation.LabelledCell"> <attribute name="label">'Title'</attribute> <attribute name="type">@net.java.amateras.xlsbeans.annotation.LabelledCellType@Right</attribute> </annotation> </method> </class> </annotations>
XLSBeansでは使用しませんが、フィールドにアノテーションを付与することも可能です。
<?xml version="1.0" encoding="utf-8"?> <annotations> <class name="net.java.amateras.xlsbeans.example.SheetObject"> <field name="setTitle"> <annotation name="..."> ... </annotation> </field> </class> </annotations>
外部XMLファイルを使う場合、ハードコードされたアノテーションを外部XMLファイルの内容でオーバーライドすることが可能です。 読み込み時は以下のようにExcelファイルとXMLファイルの両方をXMLBeans#load()メソッドに渡します。
SheetObject sheet = XLSBeans.load( new FileInputStream("example.xls"), new FileInputStream("example.xml"), SheetObject.class);
なお、AnnotationReaderクラスを使用することで、XLSBeansのダイナミック・アノテーション 機能を別のプログラムでも利用することが可能です。
// XMLファイルの読み込み XMLInfo info = XMLLoader.load(new FileInputStream("example.xml")); // AnnotationReaderのインスタンスを作成 AnnotationReader reader = new AnnotationReader(info); // SheetObjectクラスに付与されたSheetアノテーションを取得 Sheet sheet = reader.getAnnotation(SheetObject.class, Sheet.class);
Class
やMethod
、Field
オブジェクトから直接アノテーションを
取得する代わりにAnnotationReader
を使えば、XMLで宣言されたアノテーションと、クラスに
埋め込まれているアノテーションを区別せずに取得することができます。AnnotationReader
には
この他にもメソッド、フィールドに付与されたアノテーションを取得するためのメソッドも用意されています。
XLSBeansではFieldProcessor
インターフェースを実装したクラスによってアノテーションの処理を行います。
デフォルトではこのドキュメントに記述されているアノテーション用のFieldProcessor
が用意されていますが、
独自アノテーションを定義しこれに対応したFieldProcessor
をXLSBeansに追加することが可能です。
独自のアノテーションおよび、FieldProcessor
をXLSBeansに登録するにはクラスパスのルートに
xlsbeans.properties というプロパティファイルを作成し、
アノテーションのクラス名とFieldProcessor
実装クラスのクラス名を以下のように列挙します。
なお、この方法で登録を行う場合、FieldProcessor
実装クラスは引数なしのコンストラクタを持っている必要がある点に注意してください。
# アノテーションのクラス名 = FieldProcessorのクラス名 xlsbeans.sample.SampleAnnotation = xlsbeans.sample.SampleFieldProcessor
また、Javaソースコード中で直接ファクトリにFieldProcessor
実装クラスを登録することも可能です。
FieldProcessorFactory.registerProcessor( SampleAnnotation.class, new SampleFieldProcessor());