1. 基本的な使い方

本ライブラリは、Excelファイルをアノテーションを用いてJavaBeansにマッピングするライブラリ「XLSBeans」を拡張し、機能を追加したものです。

違いの詳細は、「 XLSBeansとの違い 」を参照してください。

1.1. ダウンロード

Mavenを使用する場合は pom.xml に以下の記述を追加してください。

コード - 1.1.1 pom.xmlの依存関係
1
2
3
4
5
<dependency>
    <groupId>com.github.mygreen</groupId>
    <artifactId>xlsmapper</artifactId>
    <version>2.2</version>
</dependency>

本ライブラリは、ロギングライブラリ SLF4j を使用しているため、好きな実装を追加してください。

コード - 1.1.2 ロギングライブラリの実装の追加(Logbackの場合)
1
2
3
4
5
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.10</version>
</dependency>

1.2. 前提条件

本ライブラリの前提条件を以下に示します。

表 - 1.2.1 前提条件

項目

Java

ver.1.8

Apache POI

ver.4.0+。ver.5.1.0推奨。

Spring Framework (option)

ver.3.0+

Bean Validation (option)
ver.1.0/1.1/2.0
(Hibernate Validator 4.x/5.x/6.x)

1.3. マッピングの基本

次のような表のExcelシートをマッピングする例を説明します。

_images/howto_load.png

図 - 1.3.1 基本的なマッピング

1.3.1. 読み込み方の基本

まず、シート1つに対して、POJOクラスを作成します。

  • シート名を指定するために、アノテーション @XlsSheet をクラスに付与します。

  • 見出し付きのセル「Date」をマッピングするフィールドに、アノテーション @XlsLabelledCell に付与します。

  • 表「User List」をマッピングするListのフィールドに、アノテーション @XlsHorizontalRecords を付与します。

コード - 1.3.1 シート用のPOJOクラスの定義
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
@XlsSheet(name="List")
public class UserSheet {

    @XlsLabelledCell(label="Date", type=LabelledCellType.Right)
    Date createDate;

    @XlsHorizontalRecords(tableLabel="User List")
    List<UserRecord> users;

}

続いて、表「User List」の1レコードをマッピングするための、POJOクラスを作成します。

  • レコードの列をマッピングするために、アノテーション @XlsColumn をフィールドに付与します。

  • フィールドのクラスタイプが、intや列挙型の場合もマッピングできます。

コード - 1.3.2 レコード用のPOJOクラスの定義
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
public class UserRecord {

    @XlsColumn(columnName="ID")
    int no;

    @XlsColumn(columnName="Class", merged=true)
    String className;

    @XlsColumn(columnName="Name")
    String name;

    @XlsColumn(columnName="Gender")
    Gender gender;

}

// 性別を表す列挙型の定義
public enum Gender {
    male, female;
}

作成したPOJOを使ってシートを読み込むときは、 XlsMapper#load メソッドを利用します。

コード - 1.3.3 シートの読み込み
1
2
3
4
5
XlsMapper xlsMapper = new XlsMapper();
UserSheet sheet = xlsMapper.load(
    new FileInputStream("example.xlsx"), // 読み込むExcelファイル。
    UserSheet.class                      // シートマッピング用のPOJOクラス。
    );

1.3.2. 書き込み方の基本

同じシートの形式を使って、書き込み方を説明します。

まず、書き込み先のテンプレートとなるExcelシートを用意します。 レコードなどは空を設定します。

_images/howto_save.png

図 - 1.3.2 データが空のテンプレートファイル

続いて、読み込み時に作成したシート用のマッピングクラスに、書き込み時の設定を付け加えるために修正します。

  • セル「Date」の書き込み時の書式を指定するために、アノテーション @XlsDateTimeConverter に付与します。

    • 属性 excelPattern でExcelのセルの書式を設定します。

  • 表「User List」のレコードを追加する操作を指定するために、アノテーション @XlsRecordOption を付与し、その属性 overOperation を指定します。

    • テンプレート上は、レコードが1行分しかないですが、実際に書き込むレコード数が2つ以上の場合、足りなくなるため、その際のシートの操作方法を指定します。

    • 今回の OverOperation#Insert は、行の挿入を行います。

// シート用のPOJOクラスの定義
@XlsSheet(name="List")
public class UserSheet {

    @XlsLabelledCell(label="Date", type=LabelledCellType.Right)
    @XlsDateTimeConverter(excelPattern="yyyy/m/d")
    Date createDate;

    @XlsHorizontalRecords(tableLabel="User List")
    @XlsRecordOption(overOperation=OverOperation.Insert)
    List<UserRecord> users;

}

修正したPOJOを使ってシートを書き込むときは、 XlsMapper#save メソッドを利用します。

// 書き込むシート情報の作成
UserSheet sheet = new UserSheet();
sheet.createDate = new Date();

List<UserRecord> users = new 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.xlsx"), // テンプレートのExcelファイル
    new FileOutputStream("out.xlsx"),     // 書き込むExcelファイル
    sheet                                // 作成したデータ
    );

1.4. 読み込み方

1.4.1. 単一のシートを読み込む場合

XlsMapperはアノテーションを付与してJavaBeansとExcelをマッピングするライブラリです。 アノテーション @XlsSheet を付与したJavaBeanを作成したうえで以下のようにして読み込みを行います。

XlsMapper xlsMapper = new XlsMapper();
SampleSheet sheet = xlsMapper.load(
    new FileInputStream("example.xls"), // 読み込むExcelファイル
    SampleSheet.class                   // アノテーションを付与したクラス。
    );

なお、@XlsCell@XlsLabelledCell@XlsColumn アノテーションでマッピングするプロパティにおいて、マッピングできる型は、 型変換用アノテーション を使用することでカスタマイズできます。

より具体的な使用例はXlsMapperのディストリビューションに同梱されているテストケースのソースコードをご覧ください。

XlsMapperは、Apache POIを使用してExcelのシートの読み込みと書き込みを行います。 拡張子がxlsのExcel2003形式、xlsxのExcel2007形式と特に区別なく読み込むことができます。

Apache POIは、ver.3.5以上に対応しています。

1.4.2. 複数のシートを読み込む場合

複数のシートを読み込む場合、XlsMapper#loadMultplue(...) を使用します。

シートの読み込み先のJavaBeansが異なる場合、クラスタイプを配列として渡します。 戻り値は配列Object[]として返されます。

XlsMapper xlsMapper = new XlsMapper();
Object[] sheets = xlsMapper.loadMultiple(
    new FileInputStream("example.xls"),                  // 読み込むExcelファイル
    new Class[]{SampleSheet1.class, SampleSheet2.class}  // アノテーションを付与したクラス。
    );

アノテーション @XlsSheet(regex="正規表現+") のように、シート名を正規表現で指定した場合、 シート内の表の形式は同じですが、名前が異なる複数のシートとしを読み込むことができます。

XlsMapper xlsMapper = new XlsMapper();
SampleSheet[] sheets = new XlsMapper().loadMultiple(
    new FileInputStream("example.xls"),  // 読み込むExcelファイル
    SampleSheet.class                    // アノテーションを付与したクラス。
    );

1.5. 書き込み方

1.5.1. 単一のシートの書き込む場合

書き込む際には、@XlsSheet アノテーションを付与したJavaBeansのクラスのインスタンスを渡します。 また、雛形となるテンプレートのシートを記述しているExcelファイルを引数に渡します。

SampleSheet sheet = //... POJOのインスタンス。

XlsMapper xlsMapper = new XlsMapper();
xlsMapper.save(
    new FileInputStream("template.xls"), // テンプレートのExcelファイル
    new FileOutputStream("example.xls"), // 書き込むExcelファイル
    sheet                                // JavaBeansのインスタンス
    );

書き込むExcelファイルの形式は、テンプレートとなるExcelファイルと同じ形式になります。 そのため、テンプレートファイルのExcelファイルがxls(Excel2003形式)で、 書き込むExcelファイルの拡張子をxlsx(2007形式)を指定しても、xls(Excel2003形式)となります。

アノテーション @XlsSheet(regexp="正規表現*") のようにシート名を正規表現で定義している場合、 書き込み先のシート名はアノテーション @XlsSheetName を付与したフィールドを元に決定します。

そのため、書き込むシート名を予め設定しておく必要があります。

/** 正規表現で指定する場合 */
@XlsSheet(regex="Sheet_[0-9]+")
public class SampleSheet {
  @XlsSheetName
  public String sheetName;
}

SampleSheet sheet = //... POJOのインスタンス。
sheet.sheetName = "Sheet_1"; // 予めシート名を設定しておく必要があります。

XlsMapper xlsMapper = new XlsMapper();
xlsMapper.save(
    new FileInputStream("template.xls"), // テンプレートのExcelファイル
    new FileOutputStream("example.xls"), // 書き込むExcelファイル
    sheet         // JavaBeansのインスタンス
    );

1.5.2. 複数のシートを書き込む場合

複数のシートを読み込む場合、XlsMapper#saveMultplue(...) を使用します。 書き込むJavaBeansのクラスのインスタンスは、アノテーション @XlsSheet を付与する必要があります。 シートのオブジェクトは配列として渡します。

SheetSheet1 sheet1 = //... POJOのインスタンス。
SheetSheet2 sheet2 = //... POJOのインスタンス。

new XlsMapper().saveMultiple(
    new FileInputStream("template.xls"), // テンプレートのExcelファイル
    new FileOutputStream("example.xls"), // 書き込むExcelファイル
    new Object[]{sheet1, sheet2}         // JavaBeansのインスタンスの配列
    );

注釈

アノテーション @XlsSheet(regexp="正規表現*") のようにシート名を正規表現で定義している場合、 書き込み先のシート名はアノテーション @XlsSheetName を付与したフィールドを元に決定します。

テンプレートのExcelファイル中にシートが1つしかない場合、書き込む個数分コピーしておく必要があります。 このような場合、書き込み対象のテンプレートファイルを事前に処理しておきます。

// 正規表現で指定する場合
@XlsSheet(regex="Sheet_[0-9]+")
public class SampleSheet {

    // シート名をマッピングするフィールド
    @XlsSheetName
    private String sheetName;
    ...
}


// 正規表現による複数のシートを出力する場合。
// 書き込み時に、シート名を設定して、一意に関連づけます。
SampleSheet sheet1 = new SampleSheet();
sheet1.sheetName = "Sheet_1"; // シート名の設定

SampleSheet sheet2 = new SampleSheet();
sheet2.sheetName = "Sheet_2"; // シート名の設定

SampleSheet sheet3 = new SampleSheet();
sheet3.sheetName = "Sheet_3"; // シート名の設定

SampleSheet[] sheets = new SampleSheet[]{sheet1, sheet2, sheet3};

// シートのクローン
Workbook workbook = WorkbookFactory.create(new FileInputStream("template.xlsx"));
Sheet templateSheet = workbook.getSheet("XlsSheet(regexp)");
for(SampleSheet sheetObj : sheets) {
    int sheetIndex = workbook.getSheetIndex(templateSheet);
    Sheet cloneSheet = workbook.cloneSheet(sheetIndex);
    workbook.setSheetName(workbook.getSheetIndex(cloneSheet), sheetObj.sheetName);
}

// コピー元のシートを削除する
workbook.removeSheetAt(workbook.getSheetIndex(templateSheet));

// クローンしたシートファイルを、一時ファイルに一旦出力する。
File cloneTemplateFile = File.createTempFile("template", ".xlsx");
workbook.write(new FileOutputStream(cloneTemplateFile));

// 複数のシートの書き込み
XlsMapper xlsMapper = new XlsMapper();
xlsMapper.saveMultiple(
        new FileInputStream(cloneTemplateFile), // クローンしたシートを持つファイルを指定する
        new FileOutputStream("out.xlsx"),
        sheets);