3
3
using System . Collections . Generic ;
4
4
using System . Linq ;
5
5
using System . Linq . Dynamic . Core . Exceptions ;
6
+ using System . Reflection ;
7
+
6
8
using ClosedXML . Excel ;
7
9
using ClosedXML . Report . Excel ;
8
10
using ClosedXML . Report . Options ;
@@ -94,7 +96,7 @@ private static RangeTemplate Parse(string name, IXLRange range, TempSheetBuffer
94
96
result . _cells . AddNewRow ( ) ;
95
97
}
96
98
97
- result . _mergedRanges = sheet . MergedRanges . Where ( x => range . Contains ( x ) && ! innerRanges . Any ( nr=> nr . Ranges . Any ( r=> r . Contains ( x ) ) ) ) . ToArray ( ) ;
99
+ result . _mergedRanges = sheet . MergedRanges . Where ( x => range . Contains ( x ) && ! innerRanges . Any ( nr => nr . Ranges . Any ( r => r . Contains ( x ) ) ) ) . ToArray ( ) ;
98
100
sheet . MergedRanges . RemoveAll ( result . _mergedRanges . Contains ) ;
99
101
100
102
result . ParseTags ( range ) ;
@@ -132,21 +134,21 @@ private static IEnumerable<IXLNamedRange> GetInnerRanges(IXLRange prng)
132
134
{
133
135
var containings = prng . GetContainingNames ( ) . ToArray ( ) ;
134
136
return from nr in containings
135
- let br = nr . Ranges
136
- . Any ( rng => containings
137
- . Where ( rr => rr != nr )
138
- . SelectMany ( rr => rr . Ranges )
139
- . Any ( r => r . Contains ( rng ) ) )
140
- where ! br
141
- select nr ;
137
+ let br = nr . Ranges
138
+ . Any ( rng => containings
139
+ . Where ( rr => rr != nr )
140
+ . SelectMany ( rr => rr . Ranges )
141
+ . Any ( r => r . Contains ( rng ) ) )
142
+ where ! br
143
+ select nr ;
142
144
}
143
145
144
146
public IReportBuffer Generate ( object [ ] items )
145
147
{
146
148
_evaluator . AddVariable ( "items" , items ) ;
147
149
foreach ( var v in _globalVariables )
148
150
{
149
- _evaluator . AddVariable ( "@" + v . Key , v . Value ) ;
151
+ _evaluator . AddVariable ( "@" + v . Key , v . Value ) ;
150
152
}
151
153
_rangeTags . Reset ( ) ;
152
154
@@ -208,7 +210,7 @@ private void VerticalTable(object[] items, FormulaEvaluator evaluator)
208
210
}
209
211
210
212
var newRowRng = _buff . GetRange ( startAddr , rowEnd ) ;
211
- foreach ( var mrg in _mergedRanges . Where ( r=> ! _optionsRow . Contains ( r ) ) )
213
+ foreach ( var mrg in _mergedRanges . Where ( r => ! _optionsRow . Contains ( r ) ) )
212
214
{
213
215
var newMrg = mrg . Relative ( _rowRange , newRowRng ) ;
214
216
newMrg . Merge ( false ) ;
@@ -258,7 +260,7 @@ private void VerticalTable(object[] items, FormulaEvaluator evaluator)
258
260
{
259
261
_rangeTags . Execute ( new ProcessingContext ( resultRange , new DataSource ( items ) , evaluator ) ) ;
260
262
// if the range was increased by processing tags (for example, Group), move the buffer to the last cell
261
- _buff . SetPrevCellToLastUsed ( ) ;
263
+ _buff . SetPrevCellToLastUsed ( ) ;
262
264
}
263
265
}
264
266
@@ -284,6 +286,28 @@ private void RenderCell(FormulaEvaluator evaluator, TemplateCell cell, params Pa
284
286
_errors . Add ( new TemplateError ( ex . Message , cell . XLCell . AsRange ( ) ) ) ;
285
287
return ;
286
288
}
289
+ catch ( TargetInvocationException )
290
+ {
291
+ /*
292
+ * item null complex objects results on TargetInvocationException when evaluating the lambda expression
293
+ * eg: Given an Array {
294
+ * items: {
295
+ * name: string,
296
+ * foo?: {
297
+ * name: string
298
+ * }
299
+ * }[]
300
+ *
301
+ * if in the template we have {{item.foo.name}} and in some of the items material property is null,
302
+ * this exception will be thrown.
303
+ *
304
+ * just add to the error list for future use and keep doing the work, other items may have the material property.
305
+ * No need to write the error in the cell since it might be a desired behaviour, but needs to go to next cell.
306
+ */
307
+ _buff . WriteValue ( string . Empty , cell . XLCell ) ;
308
+ _errors . Add ( new TemplateError ( string . Format ( "TargetInvocationException: {0}" , cell . Value ) , cell . XLCell . AsRange ( ) ) ) ;
309
+ return ;
310
+ }
287
311
288
312
IXLCell xlCell ;
289
313
if ( cell . CellType == TemplateCellType . Formula )
@@ -364,8 +388,8 @@ private void RenderSubrange(RangeTemplate ownRng, object item, FormulaEvaluator
364
388
else
365
389
{
366
390
// move current template cell to next (skip subrange)
367
- row += ownRng . _rowCnt + 1 ;
368
- while ( _cells [ iCell ] . Row <= row - 1 )
391
+ row += ownRng . _rowCnt + 1 ;
392
+ while ( _cells [ iCell ] . Row <= row - 1 )
369
393
iCell ++ ;
370
394
371
395
iCell -- ; // roll back. After it became clear that it was too much, we must go back.
0 commit comments