mygreen / xlsmapper Goto Github PK
View Code? Open in Web Editor NEWExcelのシートをJavaBean(POJO)にマッピングするライブラリ。
License: Apache License 2.0
ExcelのシートをJavaBean(POJO)にマッピングするライブラリ。
License: Apache License 2.0
折り返し設定など、POIバージョンの処理に依存する処理は、現在、リフレクションを毎回行っているが、性能に問題があるため、staticでバージョン判定やメソッド判定を行い、効率化する。
入力規則の範囲を修正する際に、新しく規則を追加しているが、実際には更新または一旦削除してから追加し直す必要がある。
文字列型の負の数(-12.34)をJavaのdouble型にマッピングする場合、エラーが発生する。
com.gh.mygreen.xlsmapper.cellconvert.TypeBindException: Fail conversion field value '-12.34' => type 'double'. Cell 'F20' map to 'com.gh.mygreen.xlsmapper.cellconvert.CellConvertNumberTest$PrimitiveRecord#d'.
at com.gh.mygreen.xlsmapper.cellconvert.AbstractCellConverter.newTypeBindException(AbstractCellConverter.java:39)
at com.gh.mygreen.xlsmapper.cellconvert.converter.AbstractNumberCellConverter.toObject(AbstractNumberCellConverter.java:72)
at com.gh.mygreen.xlsmapper.cellconvert.converter.AbstractNumberCellConverter.toObject(AbstractNumberCellConverter.java:1)
at com.gh.mygreen.xlsmapper.fieldprocessor.processor.HorizontalRecordsProcessor.loadRecords(HorizontalRecordsProcessor.java:260)
at com.gh.mygreen.xlsmapper.fieldprocessor.processor.HorizontalRecordsProcessor.loadProcess(HorizontalRecordsProcessor.java:91)
at com.gh.mygreen.xlsmapper.fieldprocessor.processor.HorizontalRecordsProcessor.loadProcess(HorizontalRecordsProcessor.java:1)
at com.gh.mygreen.xlsmapper.FieldAdaptorProxy.loadProcess(FieldAdaptorProxy.java:61)
at com.gh.mygreen.xlsmapper.XlsLoader.loadSheet(XlsLoader.java:440)
at com.gh.mygreen.xlsmapper.XlsLoader.load(XlsLoader.java:157)
at com.gh.mygreen.xlsmapper.XlsLoader.load(XlsLoader.java:67)
at com.gh.mygreen.xlsmapper.XlsMapper.load(XlsMapper.java:60)
at com.gh.mygreen.xlsmapper.cellconvert.CellConvertNumberTest.test_load_number(CellConvertNumberTest.java:58)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.text.ParseException: '-12.34' cannot less than 0.000000
at com.gh.mygreen.xlsmapper.cellconvert.converter.AbstractNumberCellConverter.parseNumber(AbstractNumberCellConverter.java:171)
at com.gh.mygreen.xlsmapper.cellconvert.converter.AbstractNumberCellConverter.toObject(AbstractNumberCellConverter.java:70)
... 36 more
型変換エラーの場合、列挙型事にメッセージを定義する必要があるため。
メッセージキーとして「cellTypeMismatch.java.lang.Enum」で判定できるようにする。
Set(集合)を書き込む場合、NullPointerExceptionが発生する。
java.lang.IllegalArgumentException: targetClass should not be null.
at com.gh.mygreen.xlsmapper.ArgUtils.notNull(ArgUtils.java:23)
at com.gh.mygreen.xlsmapper.Utils.convertToObject(Utils.java:1719)
at com.gh.mygreen.xlsmapper.cellconvert.converter.ListCellConverter.convertList(ListCellConverter.java:72)
at com.gh.mygreen.xlsmapper.cellconvert.converter.SetCellConverter.toCell(SetCellConverter.java:93)
at com.gh.mygreen.xlsmapper.cellconvert.converter.SetCellConverter.toCell(SetCellConverter.java:52)
at com.gh.mygreen.xlsmapper.fieldprocessor.processor.HorizontalRecordsProcessor.saveRecords(HorizontalRecordsProcessor.java:695)
at com.gh.mygreen.xlsmapper.fieldprocessor.processor.HorizontalRecordsProcessor.saveProcess(HorizontalRecordsProcessor.java:468)
at com.gh.mygreen.xlsmapper.fieldprocessor.processor.HorizontalRecordsProcessor.saveProcess(HorizontalRecordsProcessor.java:1)
at com.gh.mygreen.xlsmapper.FieldAdaptorProxy.saveProcess(FieldAdaptorProxy.java:65)
at com.gh.mygreen.xlsmapper.XlsSaver.saveSheet(XlsSaver.java:282)
at com.gh.mygreen.xlsmapper.XlsSaver.save(XlsSaver.java:114)
at com.gh.mygreen.xlsmapper.XlsSaver.save(XlsSaver.java:67)
at com.gh.mygreen.xlsmapper.XlsMapper.save(XlsMapper.java:191)
at com.gh.mygreen.xlsmapper.cellconvert.CollectionCellConveterTest.test_save_collection(CollectionCellConveterTest.java:262)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
シートの出力時に、@XlsHorizontalRecordsを利用して、行の追加した場合に、上部のセルのスタイルをコピーしているが、入力規則も反映すること。
・また、削除時にも、入力規則も考慮するようにする。
・名前の定義も反映できたら、なお良い。
@XlsHorizontalRecordsのレコードのカラムに、見出しセルを結合してしている場合、一方のセルが正しく取得できない。
private static class HeaderMergedRecord {
@XlsColumn(columnName="氏名")
private String name;
@XlsColumn(columnName="連絡先")
private String mail;
@XlsColumn(columnName="連絡先", headerMerged=1)
private String tel;
}
シートの読み込み時にセルに対してエラーが発生した場合、CellFieldを利用した値の検証はスキップされるはずがされない。
・validateメソッド内で、既存のエラーがあるかどうかの判定の際にパスの組み立てが間違っている。
public CellField<T> validate(final SheetBindingErrors errors) {
ArgUtils.notNull(errors, "errors");
// ↓既存のメソッド、hasErrorsを呼ぶべき。
final String fieldPath = errors.buildFieldPath(getName());
if(errors.hasFieldErrors(fieldPath)) {
// 既にフィールドに対するエラーがある場合
return this;
}
@XlsArrayConverter(itemConverter={
@XlsItemConveter={
converter={@XlsConverter(....)},
dateConverter={@XlsDaterConverter(pattern="yyyy-MM-dd")}
})
List<Date> dateList;
@XlsConverter(defaultValue="aaaa")で設定した初期値で、書き込むときにその値が不正な場合、ConverterExceptionをスローしているが、TypeBindExceptionをスローするように修正する。
POICellFormatterの式が設定されているセルの処理が、数値として処理されているため。
Calendar 型に対応する
@XlsLabelledCell(label="XXX", optional=true)と設定し、実際に指定したラベルが見つからない場合、NullPointerExceptionが発生する。
java.lang.NullPointerException
at com.gh.mygreen.xlsmapper.fieldprocessor.processor.LabelledCellProcessor.loadProcess(LabelledCellProcessor.java:36)
at com.gh.mygreen.xlsmapper.fieldprocessor.processor.LabelledCellProcessor.loadProcess(LabelledCellProcessor.java:1)
at com.gh.mygreen.xlsmapper.FieldAdaptorProxy.loadProcess(FieldAdaptorProxy.java:61)
at com.gh.mygreen.xlsmapper.XlsLoader.loadSheet(XlsLoader.java:440)
at com.gh.mygreen.xlsmapper.XlsLoader.load(XlsLoader.java:157)
at com.gh.mygreen.xlsmapper.XlsLoader.load(XlsLoader.java:105)
at com.gh.mygreen.xlsmapper.XlsMapper.load(XlsMapper.java:90)
at
@XlsVeritalRecords(headerAddress='A2')を指定していても反映されない。
@XlsHorizontalRecords(remainedRecord=RemainedRecordOperate.Delete)で書き込む先に余分な行を削除するときに、1回多く削除してしまう。
通常のCellFieldを使用したValidateの際に、クラスタイプを元にエラーコードを作成するようにする。
・エラーコード「cellFieldError.min」の場合に、「cellFieldError.min.java.util.Date」をエラーコードの候補にする。
shortに最大値+1(32768)を設定してもエラーとならず、オーバーフローを起こして、「-32768」となる。
バインディングエラーとすべき。
書き込み時に既存のセルにハイパーリンクが設定されていると、リンクが書き換わらない場合があるため、
一旦削除してから設定する。
excel-cellformatterの最新版ver0.4に対応する。
POIの日付フォーマットを独自のJaCalendarを利用しているが、JavaのSimpleDateFormatを利用するよう修正する。
・Excelの日付の書式をSimpleDateFormatの形式に変換する。
@XlsLaelledCellで値が設定されているセルの値が空のときに、Map<String, Position> positionsフィールドにてセルの位置を設定する際に、値が見出しのセルのアドレスになっている。
@XlsSheet(regexp="Sheet.+")で正規表現にてシート名を指定し、書き込む際の改善を行う。
NullPointerExceptionが発生する。
@XlsDateConverterで書式を指定しない場合、文字列型のセルをjava.util.Date型にマッピングすると例外が発生する。
com.gh.mygreen.xlsmapper.AnnotationInvalidException: Anotation '@null' attribute 'pattern' should be not empty.
at com.gh.mygreen.xlsmapper.cellconvert.converter.AbstractDateCellConverter.createDateFormat(AbstractDateCellConverter.java:95)
at com.gh.mygreen.xlsmapper.cellconvert.converter.AbstractDateCellConverter.toObject(AbstractDateCellConverter.java:70)
at com.gh.mygreen.xlsmapper.cellconvert.converter.AbstractDateCellConverter.toObject(AbstractDateCellConverter.java:1)
at com.gh.mygreen.xlsmapper.fieldprocessor.processor.HorizontalRecordsProcessor.loadRecords(HorizontalRecordsProcessor.java:260)
at com.gh.mygreen.xlsmapper.fieldprocessor.processor.HorizontalRecordsProcessor.loadProcess(HorizontalRecordsProcessor.java:91)
at com.gh.mygreen.xlsmapper.fieldprocessor.processor.HorizontalRecordsProcessor.loadProcess(HorizontalRecordsProcessor.java:1)
at com.gh.mygreen.xlsmapper.FieldAdaptorProxy.loadProcess(FieldAdaptorProxy.java:61)
at com.gh.mygreen.xlsmapper.XlsLoader.loadSheet(XlsLoader.java:440)
at com.gh.mygreen.xlsmapper.XlsLoader.load(XlsLoader.java:157)
at com.gh.mygreen.xlsmapper.XlsLoader.load(XlsLoader.java:105)
at com.gh.mygreen.xlsmapper.XlsMapper.load(XlsMapper.java:90)
at com.gh.mygreen.xlsmapper.cellconvert.DateTimeCellConverterTest.test_load_date_time(DateTimeCellConverterTest.java:60)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
@XlsNumberConverterにて、精度も指定できるようにする。
@XlsSheet(numbe=2)で正しいシート番号を指定しても、SheetNotFoundExceptionがスローされる。
@XlsVerticalRecordsは、@XlsHorizontalRecordsの列と行を入れ替えた版だが、表のタイトルの指定は@XlsHorizontalRecordsと同じにした方が現実的。
List、Array、Setの場合、書き込み時にトリム設定が有効にならない。
@XlsConverter(trim="true)
private List list;
@XlsHorizontalRecordsで配列型を書き込むときに、データが設定されているにもかかわらずレコードが書き出されない。
・POI-3.11以前の場合は、リフレクションで取得する。
・入力規則がセル範囲の指定形式の場合の対応
@XlsHoritonralRecords内のレコードクラスのプロパティにおいて、@XlsColumn(merged=true)を設定している場合、結合するときファイルを出力すると、Excelで開いたときにファイルの修復メッセージが表示される。
ブランクセルをString型にマッピングする際に、@XlsConverter(trim=true)でトリムが有効な場合、空文字を設定するようにする。
トリムが無効な場合はnullを設定する。
java.lang.NullPointerException
at com.gh.mygreen.xlsmapper.POICellFormatter.getNumericCellValue(POICellFormatter.java:165)
at com.gh.mygreen.xlsmapper.POICellFormatter.format(POICellFormatter.java:55)
at com.gh.mygreen.xlsmapper.POIUtils.getCellContents(POIUtils.java:234)
at com.gh.mygreen.xlsmapper.POIUtils.isEmptyCellContents(POIUtils.java:262)
at com.gh.mygreen.xlsmapper.fieldprocessor.processor.HorizontalRecordsProcessor.saveRecords(HorizontalRecordsProcessor.java:574)
at com.gh.mygreen.xlsmapper.fieldprocessor.processor.HorizontalRecordsProcessor.saveProcess(HorizontalRecordsProcessor.java:458)
at com.gh.mygreen.xlsmapper.fieldprocessor.processor.IterateTablesProcessor.saveMultipleHorizontalTableCell(IterateTablesProcessor.java:388)
at com.gh.mygreen.xlsmapper.fieldprocessor.processor.IterateTablesProcessor.saveTables(IterateTablesProcessor.java:313)
at com.gh.mygreen.xlsmapper.fieldprocessor.processor.IterateTablesProcessor.saveProcess(IterateTablesProcessor.java:257)
at com.gh.mygreen.xlsmapper.fieldprocessor.processor.IterateTablesProcessor.saveProcess(IterateTablesProcessor.java:1)
at com.gh.mygreen.xlsmapper.FieldAdaptorProxy.saveProcess(FieldAdaptorProxy.java:65)
・2007形式のコメントを含むシートを書き込むと、Excelで開くと警告が出て、修復する必要がある。
POI-3.10以上だと発生し、POI-3.9以下だと発生しない。
・さらに、2003形式のコメントを含むシートを書き込む場合、HoritonzalRecordsで行を挿入するケースの場合、NullPointerExceptionが発生する。
リスト型にマッピングする際に、トリム処理が有効でかつ各項目のが空の場合無視する処理が有効な場合、空の項目を無視するかどうかの判定にトリム処理が反映されない。
@XlsConverter(trim=true)
@XlsArrayConverter(ignoreEmptyItem=true)
List<String> list
・EL式をサポートを、EL式のみに対応する。他のMVELなどは除外する。
・Beanのアクセスは、JXPathを利用する。
・OgnlをMVELの実装に変更する。
@XlsLablelledCell(label="あいう", optional=true)で指定したらラベルが見つからない場合は、何もしないはずがNPEが発生する。
@XlsHorizontalRecords(terminal=RecordTerminal.Empty)の場合、レコードを設定していても、書き込まれない。
EL3.0を利用しているのに、メッセージ中にラムダ式など、EL3.0で追加された機能が利用できない。
バインディングに失敗したときに、デフォル値に設定するフラグを追加する。
@XlsConverter(defaultValue="1", failToDefault=true)
private int no;
fix v0.5
v2.0としてリリース。
MessageInterpolatorに渡す、マップの変数の項目がnullの場合、NPEが発生する。
Java-EL用のExpressionLanguageELImplを解析するクラスなのに、spring-expression用のクラスが読み込まれている。
例外ExpressionExceptionではなく、ELExceptionを使用するべき。
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.