package com.gh.mygreen.xlsmapper.cellconvert; import static org.junit.Assert.*; import static org.hamcrest.Matchers.*; import static com.gh.mygreen.xlsmapper.TestUtils.*; import java.awt.Point; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.junit.BeforeClass; import org.junit.Test; import com.gh.mygreen.xlsmapper.IsEmptyBuilder; import com.gh.mygreen.xlsmapper.XlsMapper; import com.gh.mygreen.xlsmapper.annotation.OverRecordOperate; import com.gh.mygreen.xlsmapper.annotation.RecordTerminal; import com.gh.mygreen.xlsmapper.annotation.XlsColumn; import com.gh.mygreen.xlsmapper.annotation.XlsConverter; import com.gh.mygreen.xlsmapper.annotation.XlsFormula; import com.gh.mygreen.xlsmapper.annotation.XlsHint; import com.gh.mygreen.xlsmapper.annotation.XlsHorizontalRecords; import com.gh.mygreen.xlsmapper.annotation.XlsIsEmpty; import com.gh.mygreen.xlsmapper.annotation.XlsSheet; import com.gh.mygreen.xlsmapper.validation.SheetBindingErrors; /** * 文字列の変換処理のテスタ * * @version 1.5 * @since 0.5 * @author T.TSUCHIE * */ public class TextCellConverterTest { /** * テスト結果ファイルの出力ディレクトリ */ private static File OUT_DIR; @BeforeClass public static void setUpBeforeClass() throws Exception { OUT_DIR = createOutDir(); } /** * 文字列型の読み込みテスト */ @Test public void test_load_text() throws Exception { XlsMapper mapper = new XlsMapper(); mapper.getConig().setContinueTypeBindFailure(true); try(InputStream in = new FileInputStream("src/test/data/convert.xlsx")) { SheetBindingErrors errors = new SheetBindingErrors(TextSheet.class); TextSheet sheet = mapper.load(in, TextSheet.class, errors); for(SimpleRecord record : sheet.simpleRecords) { assertRecord(record, errors); } for(FormattedRecord record : sheet.formattedRecords) { assertRecord(record, errors); } for(FormulaRecord record : sheet.formulaRecords) { assertRecord(record, errors); } } } private void assertRecord(final SimpleRecord record, final SheetBindingErrors errors) { if(record.no == 1) { // 空文字 assertThat(record.t, is(nullValue())); assertThat(record.c1, is((char)0)); assertThat(record.c2, is(nullValue())); } else if(record.no == 2) { // 通常の文字 assertThat(record.t, is("こんにちは")); assertThat(record.c1, is('あ')); assertThat(record.c2, is('か')); } else if(record.no == 3) { // 改行 assertThat(record.t, is("こんにちは\n今日はいい天気ですね。")); assertThat(record.c1, is('あ')); assertThat(record.c2, is('か')); } else if(record.no == 4) { // 数値 assertThat(record.t, is("12.34")); assertThat(record.c1, is('1')); assertThat(record.c2, is('1')); } else if(record.no == 5) { // 日時 assertThat(record.t, is("平成27年1月2日")); assertThat(record.c1, is('平')); assertThat(record.c2, is('平')); } else { fail(String.format("not support test case. No=%d.", record.no)); } } private void assertRecord(final FormattedRecord record, final SheetBindingErrors errors) { if(record.no == 1) { // 空文字 assertThat(record.t1, is("Hello")); assertThat(record.t2, is("")); assertThat(record.c1, is('a')); assertThat(record.c2, is('d')); } else if(record.no == 2) { // 通常の文字 assertThat(record.t1, is("こんにちは")); assertThat(record.t2, is("こんばんは")); assertThat(record.c1, is('あ')); assertThat(record.c2, is('か')); } else if(record.no == 3) { // 前後に空白 assertThat(record.t1, is(" こんにちは ")); assertThat(record.t2, is("こんばんは\n今日はいい星空ですね。")); assertThat(record.c1, is('あ')); assertThat(record.c2, is('か')); } else { fail(String.format("not support test case. No=%d.", record.no)); } } private void assertRecord(final FormulaRecord record, final SheetBindingErrors errors) { if(record.no == 1) { // 空文字 assertThat(record.t1, is(nullValue())); assertThat(record.c1, is('\u0000')); assertThat(record.c2, is(nullValue())); } else if(record.no == 2) { assertThat(record.t1, is("ABCDEF")); assertThat(record.c1, is('F')); assertThat(record.c2, is('A')); } else if(record.no == 3) { assertThat(record.t1, is("こんにちは")); assertThat(record.c1, is('は')); assertThat(record.c2, is('こ')); } else { fail(String.format("not support test case. No=%d.", record.no)); } } /** * 文字列型の書き込みテスト */ @Test public void test_save_text() throws Exception { // テストデータの作成 final TextSheet outSheet = new TextSheet(); // アノテーションなしのデータ作成 outSheet.add(new SimpleRecord() .comment("空文字")); outSheet.add(new SimpleRecord() .t("こんにちは") .c1("あ".charAt(0)) .c2("か".charAt(0)) .comment("通常の文字")); outSheet.add(new SimpleRecord() .t("こんにちは\n今日はいい天気ですね。") .c1("\n".charAt(0)) .c2("\n".charAt(0)) .comment("改行")); // アノテーションありのデータ作成 outSheet.add(new FormattedRecord() .comment("空文字")); outSheet.add(new FormattedRecord() .t1("こんにちは") .t2("こんばんは") .c1("あ".charAt(0)) .c2("か".charAt(0)) .comment("通常の文字")); outSheet.add(new FormattedRecord() .t1("\n\nこんにちは\n今日はいい天気ですね。 ") .t2(" こんばんは\n今日はいい星空ですね。\n") .c1(" ".charAt(0)) .c2("\n".charAt(0)) .comment("改行+前後に空白")); // 数式のデータ作成 outSheet.add(new FormulaRecord().comment(null)); outSheet.add(new FormulaRecord().comment(" AbCdeF ")); outSheet.add(new FormulaRecord().comment(" こんにちは ")); // ファイルへの書き込み XlsMapper mapper = new XlsMapper(); mapper.getConig().setContinueTypeBindFailure(true); File outFile = new File(OUT_DIR, "convert_text.xlsx"); try(InputStream template = new FileInputStream("src/test/data/convert_template.xlsx"); OutputStream out = new FileOutputStream(outFile)) { mapper.save(template, out, outSheet); } // 書き込んだファイルを読み込み値の検証を行う。 try(InputStream in = new FileInputStream(outFile)) { SheetBindingErrors errors = new SheetBindingErrors(TextSheet.class); TextSheet sheet = mapper.load(in, TextSheet.class, errors); if(sheet.simpleRecords != null) { assertThat(sheet.simpleRecords, hasSize(outSheet.simpleRecords.size())); for(int i=0; i < sheet.simpleRecords.size(); i++) { assertRecord(sheet.simpleRecords.get(i), outSheet.simpleRecords.get(i), errors); } } if(sheet.formattedRecords != null) { assertThat(sheet.formattedRecords, hasSize(outSheet.formattedRecords.size())); for(int i=0; i < sheet.formattedRecords.size(); i++) { assertRecord(sheet.formattedRecords.get(i), outSheet.formattedRecords.get(i), errors); } } if(sheet.formulaRecords != null) { assertThat(sheet.formulaRecords, hasSize(outSheet.formulaRecords.size())); for(int i=0; i < sheet.formulaRecords.size(); i++) { assertRecord(sheet.formulaRecords.get(i), outSheet.formulaRecords.get(i), errors); } } } } /** * 書き込んだレコードを検証するための * @param inRecord * @param outRecord * @param errors */ private void assertRecord(final SimpleRecord inRecord, final SimpleRecord outRecord, final SheetBindingErrors errors) { System.out.printf("%s - assertRecord::%s no=%d, comment=%s\n", this.getClass().getSimpleName(), inRecord.getClass().getSimpleName(), inRecord.no, inRecord.comment); assertThat(inRecord.no, is(outRecord.no)); assertThat(inRecord.t, is(outRecord.t)); assertThat(inRecord.c1, is(outRecord.c1)); assertThat(inRecord.c2, is(outRecord.c2)); assertThat(inRecord.comment, is(outRecord.comment)); } /** * 書き込んだレコードを検証するための * @param inRecord * @param outRecord * @param errors */ private void assertRecord(final FormattedRecord inRecord, final FormattedRecord outRecord, final SheetBindingErrors errors) { System.out.printf("%s - assertRecord::%s no=%d, comment=%s\n", this.getClass().getSimpleName(), inRecord.getClass().getSimpleName(), inRecord.no, inRecord.comment); if(inRecord.no == 1) { // 初期値の確認 assertThat(inRecord.no, is(outRecord.no)); assertThat(inRecord.t1, is("Hello")); assertThat(inRecord.t2, is("")); assertThat(inRecord.c1, is("abc".charAt(0))); assertThat(inRecord.c2, is("def".charAt(0))); assertThat(inRecord.comment, is(outRecord.comment)); } else if(inRecord.no == 2) { assertThat(inRecord.no, is(outRecord.no)); assertThat(inRecord.t1, is(outRecord.t1)); assertThat(inRecord.t2, is(outRecord.t2)); assertThat(inRecord.c1, is("あ".charAt(0))); assertThat(inRecord.c2, is("か".charAt(0))); assertThat(inRecord.comment, is(outRecord.comment)); } else if(inRecord.no == 3) { // トリムの確認 assertThat(inRecord.no, is(outRecord.no)); assertThat(inRecord.t1, is(outRecord.t1)); assertThat(inRecord.t2, is(outRecord.t2.trim())); assertThat(inRecord.c1, is("abc".charAt(0))); assertThat(inRecord.c2, is("def".charAt(0))); assertThat(inRecord.comment, is(outRecord.comment)); } else { assertThat(inRecord.no, is(outRecord.no)); assertThat(inRecord.t1, is(outRecord.t1)); assertThat(inRecord.t2, is(outRecord.t2)); assertThat(inRecord.c1, is(outRecord.c1)); assertThat(inRecord.c2, is(outRecord.c2)); assertThat(inRecord.comment, is(outRecord.comment)); } } /** * 書き込んだレコードを検証するための * @param inRecord * @param outRecord * @param errors */ private void assertRecord(final FormulaRecord inRecord, final FormulaRecord outRecord, final SheetBindingErrors errors) { System.out.printf("%s - assertRecord::%s no=%d, comment=%s\n", this.getClass().getSimpleName(), inRecord.getClass().getSimpleName(), inRecord.no, inRecord.comment); if(inRecord.no == 1) { // 空文字の確認 assertThat(inRecord.no, is(outRecord.no)); assertThat(inRecord.t1, is(nullValue())); assertThat(inRecord.c1, is('\u0000')); assertThat(inRecord.c2, is(nullValue())); assertThat(inRecord.comment, is(outRecord.comment)); } else if(inRecord.no == 2) { assertThat(inRecord.no, is(outRecord.no)); assertThat(inRecord.t1, is("ABCDEF")); assertThat(inRecord.c1, is('F')); assertThat(inRecord.c2, is('A')); assertThat(inRecord.comment, is(outRecord.comment)); } else if(inRecord.no == 3) { assertThat(inRecord.no, is(outRecord.no)); assertThat(inRecord.t1, is("こんにちは")); assertThat(inRecord.c1, is('は')); assertThat(inRecord.c2, is('こ')); assertThat(inRecord.comment, is(outRecord.comment)); } else { assertThat(inRecord.no, is(outRecord.no)); assertThat(inRecord.t1, is(outRecord.t1)); assertThat(inRecord.c1, is(outRecord.c1)); assertThat(inRecord.c2, is(outRecord.c2)); assertThat(inRecord.comment, is(outRecord.comment)); } } @XlsSheet(name="文字列型") private static class TextSheet { @XlsHint(order=1) @XlsHorizontalRecords(tableLabel="文字列型(アノテーションなし)", terminal=RecordTerminal.Border, ignoreEmptyRecord=true, overRecord=OverRecordOperate.Insert) private List<SimpleRecord> simpleRecords; @XlsHint(order=2) @XlsHorizontalRecords(tableLabel="文字列型(初期値、書式)", terminal=RecordTerminal.Border, ignoreEmptyRecord=true, overRecord=OverRecordOperate.Insert) private List<FormattedRecord> formattedRecords; @XlsHint(order=3) @XlsHorizontalRecords(tableLabel="文字列型(数式)", terminal=RecordTerminal.Border, overRecord=OverRecordOperate.Insert) private List<FormulaRecord> formulaRecords; /** * レコードを追加する。noを自動的に付与する。 * @param record * @return */ public TextSheet add(SimpleRecord record) { if(simpleRecords == null) { this.simpleRecords = new ArrayList<>(); } this.simpleRecords.add(record); record.no(simpleRecords.size()); return this; } /** * レコードを追加する。noを自動的に付与する。 * @param record * @return */ public TextSheet add(FormattedRecord record) { if(formattedRecords == null) { this.formattedRecords = new ArrayList<>(); } this.formattedRecords.add(record); record.no(formattedRecords.size()); return this; } /** * レコードを追加する。noを自動的に付与する。 * @param record * @return */ public TextSheet add(FormulaRecord record) { if(formulaRecords == null) { this.formulaRecords = new ArrayList<>(); } this.formulaRecords.add(record); record.no(formulaRecords.size()); return this; } } /** * 文字列型 - アノテーションなし * */ private static class SimpleRecord { private Map<String, Point> positions; private Map<String, String> labels; @XlsColumn(columnName="No.") private int no; @XlsColumn(columnName="String型") private String t; @XlsColumn(columnName="char型") private char c1; @XlsColumn(columnName="Character型") private Character c2; @XlsColumn(columnName="備考") private String comment; @XlsIsEmpty public boolean isEmpty() { return IsEmptyBuilder.reflectionIsEmpty(this, "positions", "labels", "no"); } public SimpleRecord no(int no) { this.no = no; return this; } public SimpleRecord t(String t) { this.t = t; return this; } public SimpleRecord c1(char c1) { this.c1 = c1; return this; } public SimpleRecord c2(Character c2) { this.c2 = c2; return this; } public SimpleRecord comment(String comment) { this.comment = comment; return this; } } /** * 文字列型 - アノテーションあり */ private static class FormattedRecord { private Map<String, Point> positions; private Map<String, String> labels; @XlsColumn(columnName="No.") private int no; @XlsConverter(defaultValue="Hello") @XlsColumn(columnName="String型(初期値)") private String t1; @XlsConverter(trim=true) @XlsColumn(columnName="String型(トリム)") private String t2; @XlsConverter(defaultValue="abc", trim=true) @XlsColumn(columnName="char型") private char c1; @XlsConverter(defaultValue="def", trim=true) @XlsColumn(columnName="Character型") private Character c2; @XlsColumn(columnName="備考") private String comment; @XlsIsEmpty public boolean isEmpty() { return IsEmptyBuilder.reflectionIsEmpty(this, "positions", "labels", "no"); } public FormattedRecord no(int no) { this.no = no; return this; } public FormattedRecord t1(String t1) { this.t1 = t1; return this; } public FormattedRecord t2(String t2) { this.t2 = t2; return this; } public FormattedRecord c1(char c1) { this.c1 = c1; return this; } public FormattedRecord c2(Character c2) { this.c2 = c2; return this; } public FormattedRecord comment(String comment) { this.comment = comment; return this; } } /** * 文字列型 - 数式 */ private static class FormulaRecord { private Map<String, Point> positions; private Map<String, String> labels; @XlsColumn(columnName="No.") private int no; @XlsColumn(columnName="String型") @XlsFormula("UPPER(TRIM(E{rowNumber}))") private String t1; @XlsColumn(columnName="char型") @XlsFormula("RIGHT(TRIM(E${rowNumber}))") private char c1; @XlsColumn(columnName="Character型") @XlsFormula("LEFT(TRIM(E${rowNumber}))") private Character c2; @XlsColumn(columnName="備考") private String comment; public FormulaRecord no(int no) { this.no = no; return this; } public FormulaRecord t1(String t1) { this.t1 = t1; return this; } public FormulaRecord c1(char c1) { this.c1 = c1; return this; } public FormulaRecord c2(Character c2) { this.c2 = c2; return this; } public FormulaRecord comment(String comment) { this.comment = comment; return this; } } }