@@ -32,23 +32,127 @@ public static class Excel
3232 /// <param name="sheetIndex">Which sheet to read.</param>
3333 /// <returns>The <see cref="IEnumerable{T}"/> loading from excel.</returns>
3434 public static IEnumerable < T > Load < T > ( string excelFile , int startRow = 1 , int sheetIndex = 0 ) where T : class , new ( )
35+ => Load < T > ( excelFile , Setting , startRow , sheetIndex ) ;
36+
37+ /// <summary>
38+ /// Loading <see cref="IEnumerable{T}"/> from specified excel file. ///
39+ /// </summary>
40+ /// <typeparam name="T">The type of the model.</typeparam>
41+ /// <param name="excelFile">The excel file.</param>
42+ /// <param name="excelSetting">The excel setting to use to load data.</param>
43+ /// <param name="startRow">The row to start read.</param>
44+ /// <param name="sheetIndex">Which sheet to read.</param>
45+ /// <returns>The <see cref="IEnumerable{T}"/> loading from excel.</returns>
46+ public static IEnumerable < T > Load < T > ( string excelFile , ExcelSetting excelSetting , int startRow = 1 , int sheetIndex = 0 ) where T : class , new ( )
3547 {
36- if ( ! File . Exists ( excelFile ) )
37- {
38- throw new FileNotFoundException ( ) ;
39- }
48+ if ( ! File . Exists ( excelFile ) ) throw new FileNotFoundException ( ) ;
49+
50+ return Load < T > ( File . OpenRead ( excelFile ) , excelSetting , startRow , sheetIndex ) ;
51+ }
52+
53+ /// <summary>
54+ /// Loading <see cref="IEnumerable{T}"/> from specified excel file. ///
55+ /// </summary>
56+ /// <typeparam name="T">The type of the model.</typeparam>
57+ /// <param name="excelFile">The excel file.</param>
58+ /// <param name="sheetName">Which sheet to read.</param>
59+ /// <param name="startRow">The row to start read.</param>
60+ /// <returns>The <see cref="IEnumerable{T}"/> loading from excel.</returns>
61+ public static IEnumerable < T > Load < T > ( string excelFile , string sheetName , int startRow = 1 ) where T : class , new ( )
62+ => Load < T > ( excelFile , Setting , sheetName , startRow ) ;
63+
64+ /// <summary>
65+ /// Loading <see cref="IEnumerable{T}"/> from specified excel file. ///
66+ /// </summary>
67+ /// <typeparam name="T">The type of the model.</typeparam>
68+ /// <param name="excelFile">The excel file.</param>
69+ /// <param name="excelSetting">The excel setting to use to load data.</param>
70+ /// <param name="sheetName">Which sheet to read.</param>
71+ /// <param name="startRow">The row to start read.</param>
72+ /// <returns>The <see cref="IEnumerable{T}"/> loading from excel.</returns>
73+ public static IEnumerable < T > Load < T > ( string excelFile , ExcelSetting excelSetting , string sheetName , int startRow = 1 ) where T : class , new ( )
74+ {
75+ if ( ! File . Exists ( excelFile ) ) throw new FileNotFoundException ( ) ;
4076
41- var workbook = InitializeWorkbook ( excelFile ) ;
77+ return Load < T > ( File . OpenRead ( excelFile ) , excelSetting , sheetName , startRow ) ;
78+ }
79+
80+ /// <summary>
81+ /// Loading <see cref="IEnumerable{T}"/> from specified excel file. ///
82+ /// </summary>
83+ /// <typeparam name="T">The type of the model.</typeparam>
84+ /// <param name="excelStream">The excel stream.</param>
85+ /// <param name="startRow">The row to start read.</param>
86+ /// <param name="sheetIndex">Which sheet to read.</param>
87+ /// <returns>The <see cref="IEnumerable{T}"/> loading from excel.</returns>
88+ public static IEnumerable < T > Load < T > ( Stream excelStream , int startRow = 1 , int sheetIndex = 0 ) where T : class , new ( )
89+ => Load < T > ( excelStream , Setting , startRow , sheetIndex ) ;
4290
43- // currently, only handle sheet one (or call side using foreach to support multiple sheet)
91+ /// <summary>
92+ /// Loading <see cref="IEnumerable{T}"/> from specified excel file. ///
93+ /// </summary>
94+ /// <typeparam name="T">The type of the model.</typeparam>
95+ /// <param name="excelStream">The excel stream.</param>
96+ /// <param name="excelSetting">The excel setting to use to load data.</param>
97+ /// <param name="startRow">The row to start read.</param>
98+ /// <param name="sheetIndex">Which sheet to read.</param>
99+ /// <returns>The <see cref="IEnumerable{T}"/> loading from excel.</returns>
100+ public static IEnumerable < T > Load < T > ( Stream excelStream , ExcelSetting excelSetting , int startRow = 1 , int sheetIndex = 0 ) where T : class , new ( )
101+ {
102+ var workbook = InitializeWorkbook ( excelStream ) ;
103+
104+ // currently, only handle one sheet (or call side using foreach to support multiple sheet)
44105 var sheet = workbook . GetSheetAt ( sheetIndex ) ;
106+ if ( null == sheet ) throw new ArgumentException ( $ "Excel sheet with specified index [{ sheetIndex } ] not found", nameof ( sheetIndex ) ) ;
107+
108+ return Load < T > ( sheet , _formulaEvaluator , excelSetting , startRow ) ;
109+ }
110+
111+ /// <summary>
112+ /// Loading <see cref="IEnumerable{T}"/> from specified excel file. ///
113+ /// </summary>
114+ /// <typeparam name="T">The type of the model.</typeparam>
115+ /// <param name="excelStream">The excel stream.</param>
116+ /// <param name="sheetName">Which sheet to read.</param>
117+ /// <param name="startRow">The row to start read.</param>
118+ /// <returns>The <see cref="IEnumerable{T}"/> loading from excel.</returns>
119+ public static IEnumerable < T > Load < T > ( Stream excelStream , string sheetName , int startRow = 1 ) where T : class , new ( )
120+ => Load < T > ( excelStream , Setting , sheetName , startRow ) ;
121+
122+ /// <summary>
123+ /// Loading <see cref="IEnumerable{T}"/> from specified excel file. ///
124+ /// </summary>
125+ /// <typeparam name="T">The type of the model.</typeparam>
126+ /// <param name="excelStream">The excel stream.</param>
127+ /// <param name="excelSetting">The excel setting to use to load data.</param>
128+ /// <param name="sheetName">Which sheet to read.</param>
129+ /// <param name="startRow">The row to start read.</param>
130+ /// <returns>The <see cref="IEnumerable{T}"/> loading from excel.</returns>
131+ public static IEnumerable < T > Load < T > ( Stream excelStream , ExcelSetting excelSetting , string sheetName , int startRow = 1 ) where T : class , new ( )
132+ {
133+ if ( string . IsNullOrWhiteSpace ( sheetName ) ) throw new ArgumentException ( $ "sheet name cannot be null or whitespace", nameof ( sheetName ) ) ;
134+
135+ var workbook = InitializeWorkbook ( excelStream ) ;
136+
137+ // currently, only handle one sheet (or call side using foreach to support multiple sheet)
138+ var sheet = workbook . GetSheet ( sheetName ) ;
139+ if ( null == sheet ) throw new ArgumentException ( $ "Excel sheet with specified name [{ sheetName } ] not found", nameof ( sheetName ) ) ;
140+
141+ return Load < T > ( sheet , _formulaEvaluator , excelSetting , startRow ) ;
142+ }
143+
144+ public static IEnumerable < T > Load < T > ( ISheet sheet , IFormulaEvaluator formulaEvaluator , int startRow = 1 ) where T : class , new ( )
145+ => Load < T > ( sheet , formulaEvaluator , Excel . Setting , startRow ) ;
146+ public static IEnumerable < T > Load < T > ( ISheet sheet , IFormulaEvaluator formulaEvaluator , ExcelSetting excelSetting , int startRow = 1 ) where T : class , new ( )
147+ {
148+ if ( null == sheet ) throw new ArgumentNullException ( nameof ( sheet ) ) ;
45149
46150 // get the writable properties
47151 var properties = typeof ( T ) . GetProperties ( BindingFlags . Public | BindingFlags . Instance | BindingFlags . SetProperty ) ;
48152
49153 bool fluentConfigEnabled = false ;
50154 // get the fluent config
51- if ( Setting . FluentConfigs . TryGetValue ( typeof ( T ) , out var fluentConfig ) )
155+ if ( excelSetting . FluentConfigs . TryGetValue ( typeof ( T ) , out var fluentConfig ) )
52156 {
53157 fluentConfigEnabled = true ;
54158 }
@@ -136,12 +240,28 @@ public static class Excel
136240 }
137241 }
138242
139- var value = row . GetCellValue ( index , _formulaEvaluator ) ;
243+ var value = row . GetCellValue ( index , formulaEvaluator ) ;
244+
245+ // give a chance to the cell value validator
246+ if ( null != config ? . CellValueValidator )
247+ {
248+ var validationResult = config . CellValueValidator ( row . RowNum - 1 , config . Index , value ) ;
249+ if ( false == validationResult )
250+ {
251+ if ( fluentConfig . SkipInvalidRows )
252+ {
253+ itemIsValid = false ;
254+ break ;
255+ }
256+
257+ throw new ArgumentException ( $ "Validation of cell value at row { row . RowNum } , column { config . Title } ({ config . Index + 1 } ) failed! Value: [{ value } ]") ;
258+ }
259+ }
140260
141261 // give a chance to the value converter.
142- if ( config ? . ValueConverter != null )
262+ if ( config ? . CellValueConverter != null )
143263 {
144- value = config . ValueConverter ( value ) ;
264+ value = config . CellValueConverter ( row . RowNum - 1 , config . Index , value ) ;
145265 }
146266
147267 if ( value == null )
@@ -173,6 +293,22 @@ public static class Excel
173293
174294 if ( itemIsValid )
175295 {
296+ // give a chance to the row data validator
297+ if ( null != fluentConfig ? . RowDataValidator )
298+ {
299+ var validationResult = fluentConfig . RowDataValidator ( row . RowNum - 1 , item ) ;
300+ if ( false == validationResult )
301+ {
302+ if ( fluentConfig . SkipInvalidRows )
303+ {
304+ itemIsValid = false ;
305+ continue ;
306+ }
307+
308+ throw new ArgumentException ( $ "Validation of row data at row { row . RowNum } failed!") ;
309+ }
310+ }
311+
176312 list . Add ( item ) ;
177313 }
178314 }
@@ -242,11 +378,12 @@ internal static object GetDefault(this Type type)
242378 }
243379
244380 private static IWorkbook InitializeWorkbook ( string excelFile )
381+ => InitializeWorkbook ( File . OpenRead ( excelFile ) ) ;
382+ private static IWorkbook InitializeWorkbook ( Stream excelStream )
245383 {
246- var extension = Path . GetExtension ( excelFile ) ;
247- var workbook = WorkbookFactory . Create ( new FileStream ( excelFile , FileMode . Open , FileAccess . Read ) ) ;
384+ var workbook = WorkbookFactory . Create ( excelStream ) ;
248385 _formulaEvaluator = workbook . GetCreationHelper ( ) . CreateFormulaEvaluator ( ) ;
249386 return workbook ;
250387 }
251388 }
252- }
389+ }
0 commit comments