Skip to content

Commit 68fecc1

Browse files
committed
Add user defined fields template generation.
Add custom user defined fields on template generation based on class type (GenerateTemplate/Async<T>).
1 parent 2975819 commit 68fecc1

6 files changed

Lines changed: 104 additions & 47 deletions

File tree

src/DynamicExcelProvider/Abstractions/IExcelWriteFactoryProvider.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -207,11 +207,12 @@ Task<IResult> GenerateAsync<TDataModel>(Stream stream, IReadOnlyCollection<TData
207207
/// </summary>
208208
/// <typeparam name="T">Generic type parameter.</typeparam>
209209
/// <param name="lcid">The lcid.</param>
210+
/// <param name="customOutFields">Custom user defined output/result fields.</param>
210211
/// <returns>
211212
/// The template.
212213
/// </returns>
213214
/// =================================================================================================
214-
IResult<byte[]> GenerateTemplate<T>(int lcid) where T : class;
215+
IResult<byte[]> GenerateTemplate<T>(int lcid, IReadOnlyCollection<string> customOutFields = null) where T : class;
215216

216217
/// -------------------------------------------------------------------------------------------------
217218
/// <summary>
@@ -220,26 +221,30 @@ Task<IResult> GenerateAsync<TDataModel>(Stream stream, IReadOnlyCollection<TData
220221
/// <typeparam name="T">Generic type parameter.</typeparam>
221222
/// <param name="stream">The stream.</param>
222223
/// <param name="lcid">The lcid.</param>
224+
/// <param name="customOutFields">Custom user defined output/result fields.</param>
223225
/// <returns>
224226
/// The template.
225227
/// </returns>
226228
/// =================================================================================================
227-
IResult GenerateTemplate<T>(MemoryStream stream, int lcid) where T : class;
229+
IResult GenerateTemplate<T>(MemoryStream stream, int lcid,
230+
IReadOnlyCollection<string> customOutFields = null) where T : class;
228231

229232
/// -------------------------------------------------------------------------------------------------
230233
/// <summary>
231234
/// Generates a template asynchronous.
232235
/// </summary>
233236
/// <typeparam name="T">Generic type parameter.</typeparam>
234237
/// <param name="lcid">The lcid.</param>
238+
/// <param name="customOutFields">Custom user defined output/result fields.</param>
235239
/// <param name="cancellationToken">
236240
/// (Optional) A token that allows processing to be cancelled.
237241
/// </param>
238242
/// <returns>
239243
/// The template asynchronous.
240244
/// </returns>
241245
/// =================================================================================================
242-
Task<IResult<byte[]>> GenerateTemplateAsync<T>(int lcid, CancellationToken cancellationToken = default) where T : class;
246+
Task<IResult<byte[]>> GenerateTemplateAsync<T>(int lcid,
247+
IReadOnlyCollection<string> customOutFields = null, CancellationToken cancellationToken = default) where T : class;
243248

244249
/// -------------------------------------------------------------------------------------------------
245250
/// <summary>
@@ -248,13 +253,15 @@ Task<IResult> GenerateAsync<TDataModel>(Stream stream, IReadOnlyCollection<TData
248253
/// <typeparam name="T">Generic type parameter.</typeparam>
249254
/// <param name="stream">The stream.</param>
250255
/// <param name="lcid">The lcid.</param>
256+
/// <param name="customOutFields">Custom user defined output/result fields.</param>
251257
/// <param name="cancellationToken">
252258
/// (Optional) A token that allows processing to be cancelled.
253259
/// </param>
254260
/// <returns>
255261
/// The template asynchronous.
256262
/// </returns>
257263
/// =================================================================================================
258-
Task<IResult> GenerateTemplateAsync<T>(MemoryStream stream, int lcid, CancellationToken cancellationToken = default) where T : class;
264+
Task<IResult> GenerateTemplateAsync<T>(MemoryStream stream, int lcid,
265+
IReadOnlyCollection<string> customOutFields = null, CancellationToken cancellationToken = default) where T : class;
259266
}
260267
}

src/DynamicExcelProvider/Helpers/DataValidationsBuildHelper.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ internal static class DataValidationsBuildHelper
5555
/// The DataValidations.
5656
/// </returns>
5757
/// =================================================================================================
58-
internal static DataValidations BuildSheetDataValidations(ref IEnumerable<PropertyInfo> properties, ref IReadOnlyCollection<PropTranslateModel> outputProps)
58+
internal static DataValidations BuildSheetDataValidations(
59+
ref IEnumerable<PropertyInfo> properties,
60+
ref IReadOnlyCollection<PropTranslateModel> outputProps)
5961
{
6062
try
6163
{

src/DynamicExcelProvider/Helpers/DocGenerateParserHelper.cs

Lines changed: 52 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
using AggregatedGenericResultMessage;
2020
using AggregatedGenericResultMessage.Abstractions;
21+
using DomainCommonExtensions.ArraysExtensions;
2122
using DomainCommonExtensions.DataTypeExtensions;
2223
using DynamicExcelProvider.Extensions;
2324
using DynamicExcelProvider.Helpers.DataTable;
@@ -34,6 +35,7 @@
3435
#endregion
3536

3637
[assembly: InternalsVisibleTo("GeneralDocumentGeneratorTests")]
38+
3739
namespace DynamicExcelProvider.Helpers
3840
{
3941
/// -------------------------------------------------------------------------------------------------
@@ -112,18 +114,18 @@ internal static IResult<byte[]> Generate<TResult>(IReadOnlyCollection<TResult> d
112114

113115
var ms = new MemoryStream();
114116
var wbDef = WorkbookParseBuildHelper.BuildAndParseToWorkbookDefinition(
115-
sheetName,
117+
sheetName,
116118
outputProps,
117119
embeddedModelCollection,
118-
data,
120+
data,
119121
false);
120122
if (wbDef.IsSuccess.IsFalse())
121123
return Result<byte[]>.Failure(wbDef.GetFirstMessage());
122124

123125
var document = SpreadsheetDocumentHelper.Instance.Write(ms, wbDef.Response);
124-
125-
return document.IsSuccess.IsFalse()
126-
? Result<byte[]>.Failure(document.Messages.FirstOrDefault()?.Message)
126+
127+
return document.IsSuccess.IsFalse()
128+
? Result<byte[]>.Failure(document.Messages.FirstOrDefault()?.Message)
127129
: Result<byte[]>.Success(ms.ToArray());
128130
}
129131

@@ -150,18 +152,18 @@ internal static IResult Generate<TResult>(Stream stream, IReadOnlyCollection<TRe
150152
var (outputProps, embeddedModelCollection) = infoDataModel.Response;
151153

152154
var wbDef = WorkbookParseBuildHelper.BuildAndParseToWorkbookDefinition(
153-
sheetName,
154-
outputProps,
155-
embeddedModelCollection,
156-
data,
155+
sheetName,
156+
outputProps,
157+
embeddedModelCollection,
158+
data,
157159
false);
158160
if (wbDef.IsSuccess.IsFalse())
159161
return Result.Failure(wbDef.GetFirstMessage());
160162

161163
var document = SpreadsheetDocumentHelper.Instance.Write(stream, wbDef.Response);
162-
163-
return document.IsSuccess.IsFalse()
164-
? Result.Failure(document.Messages.FirstOrDefault()?.Message)
164+
165+
return document.IsSuccess.IsFalse()
166+
? Result.Failure(document.Messages.FirstOrDefault()?.Message)
165167
: Result.Success();
166168
}
167169

@@ -178,7 +180,7 @@ internal static IResult<byte[]> Generate(ExcelCollectionExportConfiguration expo
178180
{
179181
var infoDataModel = (IResult<(List<PropTranslateModel>, List<PropModel>)>)WorkbookParseBuildHelper
180182
.BuildAndParseInternalModelDynamic(
181-
exportConfiguration.Configuration,
183+
exportConfiguration.Configuration,
182184
exportConfiguration.DataCollection.FirstOrDefault());
183185
if (infoDataModel.IsSuccess.IsFalse())
184186
return Result<byte[]>.Failure(infoDataModel.GetFirstMessage());
@@ -188,18 +190,18 @@ internal static IResult<byte[]> Generate(ExcelCollectionExportConfiguration expo
188190
var ms = new MemoryStream();
189191

190192
var wbDef = WorkbookParseBuildHelper.BuildAndParseToWorkbookDefinition(
191-
exportConfiguration.Configuration.SheetName,
193+
exportConfiguration.Configuration.SheetName,
192194
outputProps,
193-
embeddedModelCollection,
194-
exportConfiguration.DataCollection,
195+
embeddedModelCollection,
196+
exportConfiguration.DataCollection,
195197
true);
196198
if (wbDef.IsSuccess.IsFalse())
197199
return Result<byte[]>.Failure(wbDef.GetFirstMessage());
198200

199201
var document = SpreadsheetDocumentHelper.Instance.Write(ms, wbDef.Response);
200202

201-
return document.IsSuccess.IsFalse()
202-
? Result<byte[]>.Failure(document.Messages.FirstOrDefault()?.Message)
203+
return document.IsSuccess.IsFalse()
204+
? Result<byte[]>.Failure(document.Messages.FirstOrDefault()?.Message)
203205
: Result<byte[]>.Success(ms.ToArray());
204206
}
205207

@@ -217,26 +219,26 @@ internal static IResult Generate(Stream stream, ExcelCollectionExportConfigurati
217219
{
218220
var infoDataModel = (IResult<(List<PropTranslateModel>, List<PropModel>)>)WorkbookParseBuildHelper
219221
.BuildAndParseInternalModelDynamic(
220-
exportConfiguration.Configuration,
222+
exportConfiguration.Configuration,
221223
exportConfiguration.DataCollection.FirstOrDefault());
222224
if (infoDataModel.IsSuccess.IsFalse())
223225
return Result.Failure(infoDataModel.GetFirstMessage());
224226

225227
var (outputProps, embeddedModelCollection) = infoDataModel.Response;
226228

227229
var wbDef = WorkbookParseBuildHelper.BuildAndParseToWorkbookDefinition(
228-
exportConfiguration.Configuration.SheetName,
230+
exportConfiguration.Configuration.SheetName,
229231
outputProps,
230-
embeddedModelCollection,
232+
embeddedModelCollection,
231233
exportConfiguration.DataCollection,
232234
true);
233235
if (wbDef.IsSuccess.IsFalse())
234236
return Result.Failure(wbDef.GetFirstMessage());
235237

236238
var document = SpreadsheetDocumentHelper.Instance.Write(stream, wbDef.Response);
237239

238-
return document.IsSuccess.IsFalse()
239-
? Result.Failure(document.Messages.FirstOrDefault()?.Message)
240+
return document.IsSuccess.IsFalse()
241+
? Result.Failure(document.Messages.FirstOrDefault()?.Message)
240242
: Result.Success();
241243
}
242244

@@ -246,11 +248,15 @@ internal static IResult Generate(Stream stream, ExcelCollectionExportConfigurati
246248
/// </summary>
247249
/// <typeparam name="T">Generic type parameter.</typeparam>
248250
/// <param name="lcid">The lcid.</param>
251+
/// <param name="customOutFields">Custom user defined output/result fields.</param>
249252
/// <returns>
250253
/// The template.
251254
/// </returns>
252255
/// =================================================================================================
253-
internal static IResult<byte[]> GenerateTemplate<T>(int lcid) where T : class
256+
internal static IResult<byte[]> GenerateTemplate<T>(
257+
int lcid,
258+
IReadOnlyCollection<string> customOutFields = null)
259+
where T : class
254260
{
255261
const string sheetName = "Sheet1";
256262
var infoDataModel = WorkbookParseBuildHelper.BuildAndParseInternalModelDynamic(
@@ -260,26 +266,29 @@ internal static IResult<byte[]> GenerateTemplate<T>(int lcid) where T : class
260266

261267
var (outputProps, embeddedModelCollection) = infoDataModel.Response;
262268

269+
if (customOutFields.IsNullOrEmptyEnumerable().IsFalse())
270+
outputProps = outputProps.Where(x => customOutFields!.Contains(x.CommonName)).ToList();
271+
263272
var ms = new MemoryStream();
264273

265274
var wbDef = WorkbookParseBuildHelper.BuildAndParseToWorkbookDefinition(
266-
sheetName: sheetName,
275+
sheetName: sheetName,
267276
outputProps: outputProps,
268277
embeddedModelCollection: embeddedModelCollection,
269-
data: new List<T>(),
270-
isDynamic: true,
271-
sourceRowType: typeof(T),
278+
data: new List<T>(),
279+
isDynamic: true,
280+
sourceRowType: typeof(T),
272281
generateSheetValidations: true);
273282
if (wbDef.IsSuccess.IsFalse())
274283
return Result<byte[]>.Failure(wbDef.GetFirstMessage());
275284

276285
var document = SpreadsheetDocumentHelper.Instance.Write(
277-
stream: ms,
278-
workBook: wbDef.Response,
286+
stream: ms,
287+
workBook: wbDef.Response,
279288
appendSheetValidations: true);
280289

281-
return document.IsSuccess.IsFalse()
282-
? Result<byte[]>.Failure(document.Messages.FirstOrDefault()?.Message)
290+
return document.IsSuccess.IsFalse()
291+
? Result<byte[]>.Failure(document.Messages.FirstOrDefault()?.Message)
283292
: Result<byte[]>.Success(ms.ToArray());
284293
}
285294

@@ -290,11 +299,16 @@ internal static IResult<byte[]> GenerateTemplate<T>(int lcid) where T : class
290299
/// <typeparam name="T">Generic type parameter.</typeparam>
291300
/// <param name="stream">The stream.</param>
292301
/// <param name="lcid">The lcid.</param>
302+
/// <param name="customOutFields">Custom user defined output/result fields.</param>
293303
/// <returns>
294304
/// The template.
295305
/// </returns>
296306
/// =================================================================================================
297-
internal static IResult GenerateTemplate<T>(MemoryStream stream, int lcid) where T : class
307+
internal static IResult GenerateTemplate<T>(
308+
MemoryStream stream,
309+
int lcid,
310+
IReadOnlyCollection<string> customOutFields = null)
311+
where T : class
298312
{
299313
const string sheetName = "Sheet1";
300314
var infoDataModel = WorkbookParseBuildHelper.BuildAndParseInternalModelDynamic(
@@ -304,6 +318,9 @@ internal static IResult GenerateTemplate<T>(MemoryStream stream, int lcid) where
304318

305319
var (outputProps, embeddedModelCollection) = infoDataModel.Response;
306320

321+
if (customOutFields.IsNullOrEmptyEnumerable().IsFalse())
322+
outputProps = outputProps.Where(x => customOutFields!.Contains(x.CommonName)).ToList();
323+
307324
var wbDef = WorkbookParseBuildHelper.BuildAndParseToWorkbookDefinition(
308325
sheetName: sheetName,
309326
outputProps: outputProps,
@@ -316,8 +333,8 @@ internal static IResult GenerateTemplate<T>(MemoryStream stream, int lcid) where
316333
return Result.Failure(wbDef.GetFirstMessage());
317334

318335
var document = SpreadsheetDocumentHelper.Instance.Write(
319-
stream: stream,
320-
workBook: wbDef.Response,
336+
stream: stream,
337+
workBook: wbDef.Response,
321338
appendSheetValidations: true);
322339

323340
return document.IsSuccess.IsFalse()

src/DynamicExcelProvider/Providers/ExcelWriteFactoryProvider.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -170,21 +170,24 @@ public async Task<IResult> GenerateAsync(
170170
=> await _spreadsheetDocumentService.WriteFileAsync(stream, workBook, cancellationToken);
171171

172172
/// <inheritdoc />
173-
public IResult<byte[]> GenerateTemplate<T>(int lcid) where T : class
174-
=> DocGenerateParserHelper.GenerateTemplate<T>(lcid);
173+
public IResult<byte[]> GenerateTemplate<T>(int lcid, IReadOnlyCollection<string> customOutFields = null) where T : class
174+
=> DocGenerateParserHelper.GenerateTemplate<T>(lcid, customOutFields);
175175

176176
/// <inheritdoc />
177-
public IResult GenerateTemplate<T>(MemoryStream stream, int lcid) where T : class
178-
=> DocGenerateParserHelper.GenerateTemplate<T>(stream, lcid);
177+
public IResult GenerateTemplate<T>(MemoryStream stream, int lcid,
178+
IReadOnlyCollection<string> customOutFields = null) where T : class
179+
=> DocGenerateParserHelper.GenerateTemplate<T>(stream, lcid, customOutFields);
179180

180181
/// <inheritdoc />
181182
public async Task<IResult<byte[]>> GenerateTemplateAsync<T>(int lcid,
183+
IReadOnlyCollection<string> customOutFields = null,
182184
CancellationToken cancellationToken = default) where T : class
183-
=> await Task.Run(() => GenerateTemplate<T>(lcid), cancellationToken);
185+
=> await Task.Run(() => GenerateTemplate<T>(lcid, customOutFields), cancellationToken);
184186

185187
/// <inheritdoc />
186188
public async Task<IResult> GenerateTemplateAsync<T>(MemoryStream stream, int lcid,
189+
IReadOnlyCollection<string> customOutFields = null,
187190
CancellationToken cancellationToken = default) where T : class
188-
=> await Task.Run(() => GenerateTemplate<T>(stream, lcid), cancellationToken);
191+
=> await Task.Run(() => GenerateTemplate<T>(stream, lcid, customOutFields), cancellationToken);
189192
}
190193
}

src/tests/GeneralDocumentGeneratorTests/GenerateExcelTemplateTests.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,5 +91,33 @@ public void Generator_xlsx_Empty_Template_Stream_PublicSet_Test(int lcid)
9191
Assert.IsNotNull(fs);
9292
Assert.IsNotNull(fs.Length > 0);
9393
}
94+
95+
[DataRow(1048)]
96+
[DataRow(1033)]
97+
[TestMethod]
98+
public void Generator_xlsx_Empty_Template_Stream_PublicSet_CustomFields_Test(int lcid)
99+
{
100+
var ms = new MemoryStream();
101+
var bytesArray = DocGenerateParserHelper.GenerateTemplate<GenerateDataTemp>(
102+
ms, lcid, new[]
103+
{
104+
nameof(GenerateDataTemp.Id),
105+
nameof(GenerateDataTemp.OperationId),
106+
nameof(GenerateDataTemp.Name)
107+
});
108+
109+
if (bytesArray.IsSuccess.IsFalse())
110+
throw new Exception(bytesArray.GetFirstMessage());
111+
112+
Assert.IsTrue(bytesArray.IsSuccess);
113+
114+
var filePath = Path.Combine(Directory.GetCurrentDirectory(),
115+
$"G_xlsx_Empty_T_Stream_PublicSet_CustomFields_{lcid}_{Guid.NewGuid():N}.xlsx");
116+
using var fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
117+
fs.Write(ms.ToArray());
118+
119+
Assert.IsNotNull(fs);
120+
Assert.IsNotNull(fs.Length > 0);
121+
}
94122
}
95123
}

src/tests/GeneralDocumentGeneratorTests/Models/GenerateDataTemp.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public class GenerateDataTemp
4646
[ExcelPropName("Nume", 1048, true, 3)]
4747
public string Name { get; set; }
4848

49-
[ExcelPropValidation(ValidationType.TextLength, ValidationOperatorType.LessThan, minValue: 5, promptMessage: "Code, max length 5", errorMessage: "Maximum length!!")]
49+
[ExcelPropValidation(ValidationType.TextLength, ValidationOperatorType.LessThan, minValue: 5, promptMessage: "Code, length < 5", errorMessage: "Maximum length!!")]
5050
[ExcelPropName("Cod", 1048, true, 4)]
5151
public string Code { get; set; }
5252

0 commit comments

Comments
 (0)