Coder Social home page Coder Social logo

mygreen / xlsmapper Goto Github PK

View Code? Open in Web Editor NEW
29.0 29.0 9.0 50.92 MB

ExcelのシートをJavaBean(POJO)にマッピングするライブラリ。

License: Apache License 2.0

Java 99.52% Batchfile 0.07% Makefile 0.02% HTML 0.05% Python 0.27% JavaScript 0.03% CSS 0.03% Shell 0.03% Dockerfile 0.01%
annotation excel java poi sheet

xlsmapper's People

Contributors

dependabot[bot] avatar mygreen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

xlsmapper's Issues

POIのバージョンの判定を行う。

折り返し設定など、POIバージョンの処理に依存する処理は、現在、リフレクションを毎回行っているが、性能に問題があるため、staticでバージョン判定やメソッド判定を行い、効率化する。

@XlsHorizontalRecordsで書き込む際に入力規則の範囲修正が上手くいかない。

入力規則の範囲を修正する際に、新しく規則を追加しているが、実際には更新または一旦削除してから追加し直す必要がある。

  • 現象として、既存の規則が残ったままになり、行を追加/削除すると、入力規則の位置がおかしくなる。
  • POIで行を削除しても入力規則の範囲はそのままなので、修正する必要がある。
  • POIでは入力規則は、セルではなく、結合の用に別データとしてセルの範囲として持っている。

文字列型のセルに数値を入力し数値として取り込む場合、エラーが発生する。

文字列型の負の数(-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

集合型を書き込む時にnullを設定するとNullPointerExceptionが発生する。

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のレコードのカラムに、見出しセルを結合してしている場合、一方のセルが正しく取得できない。

  • 下記の例で、フィールドmailにtelの値が設定される。
  • プログラムのロジックを見ると、結合している列分、ループが余計に実行されている。
private static class HeaderMergedRecord {

        @XlsColumn(columnName="氏名")
        private String name;

        @XlsColumn(columnName="連絡先")
        private String mail;

        @XlsColumn(columnName="連絡先", headerMerged=1)
        private String tel;

    }

CellFieldで属性エラーがある場合でも必須チェックが実行される。

シートの読み込み時にセルに対してエラーが発生した場合、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にConverterを設定可能にする。

  • @XlsArrayConverterの要素に対して、下記のようにConverterが設定できるようにする。
  • ブリッジ用のアノテーション @XlsItemConverterを利用する。
@XlsArrayConverter(itemConverter={
    @XlsItemConveter={
             converter={@XlsConverter(....)},
             dateConverter={@XlsDaterConverter(pattern="yyyy-MM-dd")}
})
List<Date> dateList;

@XlsLabelledCell(optional=true)にしている場合NullPointerExcepionが発生する

@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 

POIの日付処理の改善

POIの日付フォーマットを独自のJaCalendarを利用しているが、JavaのSimpleDateFormatを利用するよう修正する。
・Excelの日付の書式をSimpleDateFormatの形式に変換する。

書き込む際に正規表現でシートを名を指定する場合の改善

@XlsSheet(regexp="Sheet.+")で正規表現にてシート名を指定し、書き込む際の改善を行う。

  • 正規表現で指定しても、一致するシートが1つの場合は、エラーとしないで、そのシートに書き込む。
  • @XlsSheetNameフィールドを指定していても、その値に一致しなくても、正規表現に一致するシートが1つ一致すれば、そのシートに書き込む。

文字列型のセルをjava.util.Date型にマッピングする際に、@XlsDateConverterを指定しないとエラーとなる。

@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)

@XlsVerticalRecordsで表のタイトルが上にある場合に対応する。

@XlsVerticalRecordsは、@XlsHorizontalRecordsの列と行を入れ替えた版だが、表のタイトルの指定は@XlsHorizontalRecordsと同じにした方が現実的。

  • アノテーションの属性「tableLabelTop=true」などで指定する。
  • さらに、表のラベルの位置を指定できれば、@XlsIterateTablesも対応可能。ただし、その際は、bottom属性に対応するものを追加すべき。

2003形式のExcelを書き込む場合、セルの取得時に例外が発生する。

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)

EL式関係のライブラリの整理

・EL式をサポートを、EL式のみに対応する。他のMVELなどは除外する。
・Beanのアクセスは、JXPathを利用する。
・OgnlをMVELの実装に変更する。

@XlsHorizontalRecords(terminal=RecordTerminal.Empty)だとレコードが書き込まれない。

@XlsHorizontalRecords(terminal=RecordTerminal.Empty)の場合、レコードを設定していても、書き込まれない。

  • 読み込み時には表の終端を判定する際に、セルの値が空であることに意味があるが、書き込む際にはテンプレート用のセルは空を設定しているため、処理が終了してしまう。
  • 書き込む際には、terminalの値がRecordTerminal.Emptyの場合、RecordTerminal.Borderに補正して処理する。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.