1. 基本的な使い方¶
本ライブラリは、Excelファイルをアノテーションを用いてJavaBeansにマッピングするライブラリ「XLSBeans」を拡張し、機能を追加したものです。
違いの詳細は、「 XLSBeansとの違い 」を参照してください。
1.1. ダウンロード¶
Mavenを使用する場合は pom.xml に以下の記述を追加してください。
1 2 3 4 5 | <dependency>
<groupId>com.github.mygreen</groupId>
<artifactId>xlsmapper</artifactId>
<version>2.2</version>
</dependency>
|
本ライブラリは、ロギングライブラリ SLF4j を使用しているため、好きな実装を追加してください。
1 2 3 4 5 | <dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.10</version>
</dependency>
|
1.2. 前提条件¶
本ライブラリの前提条件を以下に示します。
項目 |
値 |
---|---|
Java |
ver.1.8 |
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シートをマッピングする例を説明します。
1.3.1. 読み込み方の基本¶
まず、シート1つに対して、POJOクラスを作成します。
シート名を指定するために、アノテーション @XlsSheet をクラスに付与します。
見出し付きのセル「Date」をマッピングするフィールドに、アノテーション @XlsLabelledCell に付与します。
表「User List」をマッピングするListのフィールドに、アノテーション @XlsHorizontalRecords を付与します。
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 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 2 3 4 5 | XlsMapper xlsMapper = new XlsMapper();
UserSheet sheet = xlsMapper.load(
new FileInputStream("example.xlsx"), // 読み込むExcelファイル。
UserSheet.class // シートマッピング用のPOJOクラス。
);
|
1.3.2. 書き込み方の基本¶
同じシートの形式を使って、書き込み方を説明します。
まず、書き込み先のテンプレートとなるExcelシートを用意します。 レコードなどは空を設定します。
続いて、読み込み時に作成したシート用のマッピングクラスに、書き込み時の設定を付け加えるために修正します。
セル「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);