package com.gh.mygreen.xlsmapper; import static com.gh.mygreen.xlsmapper.TestUtils.*; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import static com.gh.mygreen.xlsmapper.xml.XmlBuilder.*; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.Date; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.WorkbookFactory; import org.junit.BeforeClass; import org.junit.Test; import com.gh.mygreen.xlsmapper.annotation.LabelledCellType; 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.XlsMapColumns; import com.gh.mygreen.xlsmapper.annotation.XlsPreSave; import com.gh.mygreen.xlsmapper.annotation.XlsSheet; import com.gh.mygreen.xlsmapper.annotation.XlsSheetName; /** * マニュアルなどに明記するためのサンプル * * @author T.TSUCHIE * */ public class SampleTest { /** * テスト結果ファイルの出力ディレクトリ */ private static File OUT_DIR; @BeforeClass public static void setUpBeforeClass() throws Exception { OUT_DIR = createOutDir(); } /** * マッピングの基本 - 読み込み */ @Test public void test_HowTo_Load() throws Exception { // シートの読み込み XlsMapper xlsMapper = new XlsMapper(); UserSheet sheet = xlsMapper.load( new FileInputStream("src/test/data/sample.xlsx"), // 読み込むExcelファイル。 UserSheet.class // シートマッピング用のPOJOクラス。 ); // assertion assertThat(sheet.createDate, is(toUtilDate(toTimestamp("2016-03-08 00:00:00.000")))); assertThat(sheet.users, hasSize(4)); for(UserRecord record : sheet.users) { if(record.no == 1) { assertThat(record.className, is("A")); assertThat(record.name, is("Ichiro")); assertThat(record.gender, is(Gender.male)); } else if(record.no == 2) { assertThat(record.className, is("A")); assertThat(record.name, is("Hanako")); assertThat(record.gender, is(Gender.female)); } else if(record.no == 3) { assertThat(record.className, is("A")); assertThat(record.name, is("Taro")); assertThat(record.gender, is(Gender.male)); } else if(record.no == 4) { assertThat(record.className, is("B")); assertThat(record.name, is("Jiro")); assertThat(record.gender, is(Gender.male)); } } } /** * マッピングの基本 - 書き込み */ @Test public void test_HowTo_Save() throws Exception { 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(); record2.no = 2; record2.className = "A"; record2.name = "Hanako"; record2.gender = Gender.female; users.add(record2); UserRecord record3 = new UserRecord(); record3.no = 3; record3.className = "B"; record3.name = "Taro"; record3.gender = Gender.female; users.add(record3); sheet.users = users; // シートの書き込み XlsMapper xlsMapper = new XlsMapper(); xlsMapper.save( new FileInputStream("src/test/data/sample_template.xlsx"), // テンプレートのExcelファイル new FileOutputStream(new File(OUT_DIR, "sample_out.xlsx")), // 書き込むExcelファイル sheet // 作成したデータ ); // assertion UserSheet inSheet = xlsMapper.load(new FileInputStream(new File(OUT_DIR, "sample_out.xlsx")), UserSheet.class); assertThat(inSheet.createDate, is(sheet.createDate)); assertThat(inSheet.users, hasSize(sheet.users.size())); for(int i=0; i < inSheet.users.size(); i++) { UserRecord inRecord = inSheet.users.get(i); assertThat(inRecord.className, is(sheet.users.get(i).className)); assertThat(inRecord.name, is(sheet.users.get(i).name)); assertThat(inRecord.gender, is(sheet.users.get(i).gender)); } } // シート用のPOJOクラスの定義 @XlsSheet(name="List") private static class UserSheet { @XlsLabelledCell(label="Date", type=LabelledCellType.Right) @XlsDateConverter(excelPattern="yyyy/m/d") Date createDate; @XlsHorizontalRecords(tableLabel="User List", overRecord=OverRecordOperate.Insert) List<UserRecord> users; } // レコード用のPOJOクラスの定義 private static class UserRecord { @XlsColumn(columnName="ID") int no; @XlsColumn(columnName="Class", merged=true) String className; @XlsColumn(columnName="Name") String name; @XlsColumn(columnName="Gender") Gender gender; } // 性別を表す列挙型の定義 private enum Gender { male, female; } /** * MapColumnsで書き込み時に、動的にカラムを増やす場合 */ @Test public void test_MapColumn_dynamic_save() throws Exception { // create data MapColumnsDynamicSheet sheet = new MapColumnsDynamicSheet(); List<MapColumnsDynamicSheet.SampleRecord> records = new ArrayList<>(); // record1 MapColumnsDynamicSheet.SampleRecord record1 = new MapColumnsDynamicSheet.SampleRecord(); record1.id = 1; record1.name = "Taro Yamada"; record1.addAttendedMap("4月1日", "出席").addAttendedMap("4月2日", "出席").addAttendedMap("4月3日", "欠席"); records.add(record1); sheet.records = records; // シートの書き込み XlsMapper xlsMapper = new XlsMapper(); xlsMapper.save( new FileInputStream("src/test/data/sample_template.xlsx"), new FileOutputStream(new File(OUT_DIR, "sample_out.xlsx")), sheet ); } // @Test public void test_mofidy_sheet() throws Exception { MapColumnsDynamicSheet.SampleRecord record1 = new MapColumnsDynamicSheet.SampleRecord(); record1.addAttendedMap("4月1日", "出席").addAttendedMap("4月2日", "出席").addAttendedMap("4月3日", "欠席"); Workbook workbook = WorkbookFactory.create(new FileInputStream("src/test/data/sample_template.xlsx")); Sheet sheet = workbook.getSheet("MapColumn(dynamic)"); XlsMapperConfig config = new XlsMapperConfig(); // 日付のセル[日付]を取得する Cell baseHeaderCell = Utils.getCell(sheet, "[日付]", 0, 0, config); List<String> dateHeaders = new ArrayList<>(record1.attendedMap.keySet()); // 1つ目の見出しの書き換え baseHeaderCell.setCellValue(dateHeaders.get(0)); // 2つ目以降の見出し列の追加 Row headerRow = baseHeaderCell.getRow(); for(int i=1; i < dateHeaders.size(); i++) { Cell headerCell = headerRow.createCell(baseHeaderCell.getColumnIndex() + i); CellStyle style = workbook.createCellStyle(); style.cloneStyleFrom(baseHeaderCell.getCellStyle()); headerCell.setCellStyle(style); headerCell.setCellValue(dateHeaders.get(i)); } // データ行の列の追加 Row valueRow = sheet.getRow(baseHeaderCell.getRowIndex() + 1); Cell baseValueCell = valueRow.getCell(baseHeaderCell.getColumnIndex()); for(int i=1; + i < dateHeaders.size(); i++) { Cell valueCell = valueRow.createCell(baseValueCell.getColumnIndex() + i); CellStyle style = workbook.createCellStyle(); style.cloneStyleFrom(baseValueCell.getCellStyle()); valueCell.setCellStyle(style); } workbook.write(new FileOutputStream(new File(OUT_DIR, "sample_out.xlsx"))); } // シート用クラス @XlsSheet(name="MapColumn(dynamic)") private static class MapColumnsDynamicSheet { @XlsHorizontalRecords(tableLabel="ユーザ一覧", overRecord=OverRecordOperate.Insert) List<SampleRecord> records; // XlsMapColumnsのマッピング用のセルを作成する @XlsPreSave public void onPreSave(final Sheet sheet, final XlsMapperConfig config) { try { final Workbook workbook = sheet.getWorkbook(); // 基準となる日付のセル[日付]を取得する Cell baseHeaderCell = Utils.getCell(sheet, "[日付]", 0, 0, config); // 書き換えるための見出しの値の取得 List<String> dateHeaders = new ArrayList<>(records.get(0).attendedMap.keySet()); // 1つ目の見出しの書き換え baseHeaderCell.setCellValue(dateHeaders.get(0)); // 2つ目以降の見出し列の追加 Row headerRow = baseHeaderCell.getRow(); for(int i=1; i < dateHeaders.size(); i++) { Cell headerCell = headerRow.createCell(baseHeaderCell.getColumnIndex() + i); CellStyle style = workbook.createCellStyle(); style.cloneStyleFrom(baseHeaderCell.getCellStyle()); headerCell.setCellStyle(style); headerCell.setCellValue(dateHeaders.get(i)); } // 2つ目以降のデータ行の列の追加 Row valueRow = sheet.getRow(baseHeaderCell.getRowIndex() + 1); Cell baseValueCell = valueRow.getCell(baseHeaderCell.getColumnIndex()); for(int i=1; + i < dateHeaders.size(); i++) { Cell valueCell = valueRow.createCell(baseValueCell.getColumnIndex() + i); CellStyle style = workbook.createCellStyle(); style.cloneStyleFrom(baseValueCell.getCellStyle()); valueCell.setCellStyle(style); } } catch (Exception e) { throw new RuntimeException(e); } } // レコード用クラス static class SampleRecord { @XlsColumn(columnName="ID") private int id; @XlsColumn(columnName="名前") private String name; @XlsMapColumns(previousColumnName="名前") private Map<String, String> attendedMap; public SampleRecord addAttendedMap(final String key, final String value) { if(attendedMap == null) { this.attendedMap = new LinkedHashMap<>(); } this.attendedMap.put(key, value); return this; } } } /** * {@link XlsSheet} - 正規表現の場合のシートのコピー */ @Test public void test_Sheet_regex_clone() throws Exception { // 正規表現による複数のシートを出力する場合。 // 書き込み時に、シート名を設定して、一意に関連づけます。 SheetRegexClone sheet1 = new SheetRegexClone(); sheet1.sheetName = "Sheet_1"; // シート名の設定 SheetRegexClone sheet2 = new SheetRegexClone(); sheet2.sheetName = "Sheet_2"; // シート名の設定 SheetRegexClone sheet3 = new SheetRegexClone(); sheet3.sheetName = "Sheet_3"; // シート名の設定 SheetRegexClone[] sheets = new SheetRegexClone[]{sheet1, sheet2, sheet3}; // シートのクローン Workbook workbook = WorkbookFactory.create(new FileInputStream("src/test/data/sample_template.xlsx")); Sheet templateSheet = workbook.getSheet("XlsSheet(regexp)"); for(SheetRegexClone 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(new File(OUT_DIR, "sample_out.xlsx")), sheets); } @XlsSheet(regex="Sheet_[0-9]+") private static class SheetRegexClone { @XlsSheetName @XlsLabelledCell(label="シート名", type=LabelledCellType.Right) private String sheetName; } /** * アノテーションのシート名の動的な変更 */ @Test public void test_overide_sheetName() throws Exception { InputStream xmlIn = createXml() .classInfo(createClass(OverrideSheetName.class) .override(true) // アノテーションを差分だけ反映する設定を有効にします。 .annotation(createAnnotation(XlsSheet.class) .attribute("name", "シート2") .buildAnnotation()) .buildClass()) .buildXml() .toInputStream(); // XMLに変換後、さらにInputStreamに変換して取得します。。 // XmlMapperクラスに直接渡せます。 OverrideSheetName sheet = new XlsMapper().load( new FileInputStream("src/test/data/sample_overrideSheetName.xlsx"), OverrideSheetName.class, xmlIn); assertThat(sheet.sheetName, is("シート2")); assertThat(sheet.description, is("変更後のシートです。")); } @XlsSheet(name="シート1") private static class OverrideSheetName { @XlsSheetName private String sheetName; @XlsLabelledCell(label="説明", type=LabelledCellType.Right) private String description; } }