@@ -51,6 +51,9 @@ final class PoijiHandler<T> implements SheetContentsHandler {
5151 private final Map <Integer , Field > columnToField ;
5252 private final Map <Integer , Field > columnToSuperClassField ;
5353 private final Set <ExcelCellName > excelCellNameAnnotations ;
54+ // Record support
55+ private final boolean isRecord ;
56+ private Map <String , Object > recordValues ;
5457
5558 PoijiHandler (Class <T > type , PoijiOptions options , Consumer <? super T > consumer ) {
5659 this .type = type ;
@@ -64,6 +67,7 @@ final class PoijiHandler<T> implements SheetContentsHandler {
6467 columnToField = new HashMap <>();
6568 columnToSuperClassField = new HashMap <>();
6669 excelCellNameAnnotations = new HashSet <>();
70+ this .isRecord = ReflectUtil .isRecord (type );
6771 }
6872
6973 private void setFieldValue (String content , Class <? super T > subclass , int column ) {
@@ -97,7 +101,11 @@ private boolean setValue(String content, Class<? super T> type, int column) {
97101 ExcelRow excelRow = field .getAnnotation (ExcelRow .class );
98102 if (excelRow != null ) {
99103 Object o = casting .castValue (field , valueOf (internalRow ), internalRow , column , options );
100- ReflectUtil .setFieldData (field , o , instance );
104+ if (isRecord ) {
105+ recordValues .put (field .getName (), o );
106+ } else {
107+ ReflectUtil .setFieldData (field , o , instance );
108+ }
101109 columnToField .put (-1 , field );
102110 }
103111 ExcelCellRange range = field .getAnnotation (ExcelCellRange .class );
@@ -106,13 +114,17 @@ private boolean setValue(String content, Class<? super T> type, int column) {
106114 ins = getInstance (field );
107115 for (Field f : field .getType ().getDeclaredFields ()) {
108116 if (setValue (f , column , content , ins )) {
109- ReflectUtil .setFieldData (field , ins , instance );
117+ if (isRecord ) {
118+ recordValues .put (field .getName (), ins );
119+ } else {
120+ ReflectUtil .setFieldData (field , ins , instance );
121+ }
110122 columnToField .put (column , f );
111123 columnToSuperClassField .put (column , field );
112124 }
113125 }
114126 } else {
115- if (setValue (field , column , content , instance )) {
127+ if (setValue (field , column , content , isRecord ? null : instance )) {
116128 columnToField .put (column , field );
117129 }
118130 }
@@ -123,12 +135,22 @@ private boolean setValue(String content, Class<? super T> type, int column) {
123135 if (!columnToField .containsKey (column )) {
124136 try {
125137 Map <String , String > excelUnknownCellsMap ;
126- field .setAccessible (true );
127- if (field .get (instance ) == null ) {
128- excelUnknownCellsMap = new HashMap <>();
129- ReflectUtil .setFieldData (field , excelUnknownCellsMap , instance );
138+ if (isRecord ) {
139+ // For records, we need to get or create the map from recordValues
140+ if (recordValues .containsKey (field .getName ())) {
141+ excelUnknownCellsMap = (Map <String , String >) recordValues .get (field .getName ());
142+ } else {
143+ excelUnknownCellsMap = new HashMap <>();
144+ recordValues .put (field .getName (), excelUnknownCellsMap );
145+ }
130146 } else {
131- excelUnknownCellsMap = (Map <String , String >) field .get (instance );
147+ field .setAccessible (true );
148+ if (field .get (instance ) == null ) {
149+ excelUnknownCellsMap = new HashMap <>();
150+ ReflectUtil .setFieldData (field , excelUnknownCellsMap , instance );
151+ } else {
152+ excelUnknownCellsMap = (Map <String , String >) field .get (instance );
153+ }
132154 }
133155 String index = indexToTitle .get (column );
134156 if (index == null ) {
@@ -146,28 +168,46 @@ private boolean setValue(String content, Class<? super T> type, int column) {
146168 if (columnToField .containsKey (-1 )) {
147169 Field field = columnToField .get (-1 );
148170 Object o = casting .castValue (field , valueOf (internalRow ), internalRow , column , options );
149- ReflectUtil .setFieldData (field , o , instance );
171+ if (isRecord ) {
172+ recordValues .put (field .getName (), o );
173+ } else {
174+ ReflectUtil .setFieldData (field , o , instance );
175+ }
150176 }
151177 if (columnToField .containsKey (column ) && columnToSuperClassField .containsKey (column )) {
152178 Field field = columnToField .get (column );
153179 Object ins ;
154180 ins = getInstance (columnToSuperClassField .get (column ));
155181 if (setValue (field , column , content , ins )) {
156- ReflectUtil .setFieldData (columnToSuperClassField .get (column ), ins , instance );
182+ if (isRecord ) {
183+ recordValues .put (columnToSuperClassField .get (column ).getName (), ins );
184+ } else {
185+ ReflectUtil .setFieldData (columnToSuperClassField .get (column ), ins , instance );
186+ }
157187 return true ;
158188 }
159- return setValue (field , column , content , instance );
189+ return setValue (field , column , content , isRecord ? null : instance );
160190 }
161191 return false ;
162192 }
163193
194+ private void setFieldValue (Field field , Object value , Object ins ) {
195+ if (isRecord && ins == null ) {
196+ // For records, store value in recordValues map
197+ recordValues .put (field .getName (), value );
198+ } else {
199+ // For regular classes, set field directly
200+ ReflectUtil .setFieldData (field , value , ins );
201+ }
202+ }
203+
164204 private boolean setValue (Field field , int column , String content , Object ins ) {
165205 ExcelCell index = field .getAnnotation (ExcelCell .class );
166206
167207 if (index != null ) {
168208 if (column == index .value ()) {
169209 Object o = casting .castValue (field , content , internalRow , column , options );
170- ReflectUtil . setFieldData (field , o , ins );
210+ setFieldValue (field , o , ins );
171211 return true ;
172212 }
173213 }
@@ -179,7 +219,7 @@ private boolean setValue(Field field, int column, String content, Object ins) {
179219 // Fix both columns mapped to name passing this condition below
180220 if (titleColumn != null && titleColumn == column ) {
181221 Object o = casting .castValue (field , content , internalRow , column , options );
182- ReflectUtil . setFieldData (field , o , ins );
222+ setFieldValue (field , o , ins );
183223 return true ;
184224 }
185225 }
@@ -192,7 +232,12 @@ private boolean setValue(Field field, int column, String content, Object ins) {
192232 Pattern pattern = Pattern .compile (expression );
193233 if (pattern .matcher (titleColumn ).matches ()) {
194234 Object o = casting .castValue (field , content , internalRow , column , options );
195- ReflectUtil .putFieldMultiValueMapData (field , titleColumn , o , ins );
235+ if (isRecord && ins == null ) {
236+ // For records, MultiValuedMap is not supported in the same way
237+ recordValues .put (field .getName (), o );
238+ } else {
239+ ReflectUtil .putFieldMultiValueMapData (field , titleColumn , o , ins );
240+ }
196241 return true ;
197242 }
198243 }
@@ -223,8 +268,12 @@ public Integer findTitleColumn(ExcelCellName excelCellName) {
223268 public void startRow (int rowNum ) {
224269 if (rowNum + 1 > options .skip ()) {
225270 internalCount += 1 ;
226- instance = ReflectUtil .newInstanceOf (type );
227- fieldInstances = new HashMap <>();
271+ if (isRecord ) {
272+ recordValues = new HashMap <>();
273+ } else {
274+ instance = ReflectUtil .newInstanceOf (type );
275+ fieldInstances = new HashMap <>();
276+ }
228277 }
229278 }
230279
@@ -234,6 +283,9 @@ public void endRow(int rowNum) {
234283 return ;
235284
236285 if (rowNum + 1 > options .skip ()) {
286+ if (isRecord ) {
287+ instance = ReflectUtil .newRecordInstance (type , recordValues );
288+ }
237289 consumer .accept (instance );
238290 }
239291 }
0 commit comments