Skip to content

Commit 74ef2b9

Browse files
committed
Add template generation from configuration
Add template generation based on user defined configuration (fields and validations).
1 parent 68fecc1 commit 74ef2b9

10 files changed

Lines changed: 634 additions & 85 deletions

File tree

src/DynamicExcelProvider/Abstractions/IExcelWriteFactoryProvider.cs

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#region U S A G E S
1818

1919
using AggregatedGenericResultMessage.Abstractions;
20+
using DynamicExcelProvider.Models.Request.Configuration;
2021
using DynamicExcelProvider.Models.Request.Configuration.Property;
2122
using DynamicExcelProvider.Models.Request.Export;
2223
using DynamicExcelProvider.WorkXCore.Models;
@@ -56,7 +57,7 @@ public interface IExcelWriteFactoryProvider
5657
/// </returns>
5758
/// =================================================================================================
5859
Task<IResult<byte[]>> GenerateCsvFromKnownAsync(
59-
IReadOnlyCollection<PropModel> embeddedModelCollection, IReadOnlyCollection<PropTranslateModel> availablePropInOutput,
60+
IReadOnlyCollection<PropModel> embeddedModelCollection, IReadOnlyCollection<PropTranslateModel> availablePropInOutput,
6061
IEnumerable<IReadOnlyList<PropNameValue>> data, CancellationToken cancellationToken = default);
6162

6263
/// -------------------------------------------------------------------------------------------------
@@ -207,7 +208,7 @@ Task<IResult> GenerateAsync<TDataModel>(Stream stream, IReadOnlyCollection<TData
207208
/// </summary>
208209
/// <typeparam name="T">Generic type parameter.</typeparam>
209210
/// <param name="lcid">The lcid.</param>
210-
/// <param name="customOutFields">Custom user defined output/result fields.</param>
211+
/// <param name="customOutFields">(Optional) Custom user defined output/result fields.</param>
211212
/// <returns>
212213
/// The template.
213214
/// </returns>
@@ -221,12 +222,12 @@ Task<IResult> GenerateAsync<TDataModel>(Stream stream, IReadOnlyCollection<TData
221222
/// <typeparam name="T">Generic type parameter.</typeparam>
222223
/// <param name="stream">The stream.</param>
223224
/// <param name="lcid">The lcid.</param>
224-
/// <param name="customOutFields">Custom user defined output/result fields.</param>
225+
/// <param name="customOutFields">(Optional) Custom user defined output/result fields.</param>
225226
/// <returns>
226227
/// The template.
227228
/// </returns>
228229
/// =================================================================================================
229-
IResult GenerateTemplate<T>(MemoryStream stream, int lcid,
230+
IResult GenerateTemplate<T>(MemoryStream stream, int lcid,
230231
IReadOnlyCollection<string> customOutFields = null) where T : class;
231232

232233
/// -------------------------------------------------------------------------------------------------
@@ -235,15 +236,15 @@ IResult GenerateTemplate<T>(MemoryStream stream, int lcid,
235236
/// </summary>
236237
/// <typeparam name="T">Generic type parameter.</typeparam>
237238
/// <param name="lcid">The lcid.</param>
238-
/// <param name="customOutFields">Custom user defined output/result fields.</param>
239+
/// <param name="customOutFields">(Optional) Custom user defined output/result fields.</param>
239240
/// <param name="cancellationToken">
240241
/// (Optional) A token that allows processing to be cancelled.
241242
/// </param>
242243
/// <returns>
243244
/// The template asynchronous.
244245
/// </returns>
245246
/// =================================================================================================
246-
Task<IResult<byte[]>> GenerateTemplateAsync<T>(int lcid,
247+
Task<IResult<byte[]>> GenerateTemplateAsync<T>(int lcid,
247248
IReadOnlyCollection<string> customOutFields = null, CancellationToken cancellationToken = default) where T : class;
248249

249250
/// -------------------------------------------------------------------------------------------------
@@ -253,15 +254,39 @@ Task<IResult<byte[]>> GenerateTemplateAsync<T>(int lcid,
253254
/// <typeparam name="T">Generic type parameter.</typeparam>
254255
/// <param name="stream">The stream.</param>
255256
/// <param name="lcid">The lcid.</param>
256-
/// <param name="customOutFields">Custom user defined output/result fields.</param>
257+
/// <param name="customOutFields">(Optional) Custom user defined output/result fields.</param>
257258
/// <param name="cancellationToken">
258259
/// (Optional) A token that allows processing to be cancelled.
259260
/// </param>
260261
/// <returns>
261262
/// The template asynchronous.
262263
/// </returns>
263264
/// =================================================================================================
264-
Task<IResult> GenerateTemplateAsync<T>(MemoryStream stream, int lcid,
265+
Task<IResult> GenerateTemplateAsync<T>(MemoryStream stream, int lcid,
265266
IReadOnlyCollection<string> customOutFields = null, CancellationToken cancellationToken = default) where T : class;
267+
268+
/// -------------------------------------------------------------------------------------------------
269+
/// <summary>
270+
/// Generates a template.
271+
/// </summary>
272+
/// <param name="stream">The stream.</param>
273+
/// <param name="configuration">The configuration.</param>
274+
/// <returns>
275+
/// The template.
276+
/// </returns>
277+
/// =================================================================================================
278+
IResult GenerateTemplate(Stream stream, ExcelTemplateWriteConfiguration configuration);
279+
280+
/// -------------------------------------------------------------------------------------------------
281+
/// <summary>
282+
/// Generates a template asynchronous.
283+
/// </summary>
284+
/// <param name="stream">The stream.</param>
285+
/// <param name="configuration">The configuration.</param>
286+
/// <returns>
287+
/// The template asynchronous.
288+
/// </returns>
289+
/// =================================================================================================
290+
Task<IResult> GenerateTemplateAsync(Stream stream, ExcelTemplateWriteConfiguration configuration);
266291
}
267292
}

src/DynamicExcelProvider/Helpers/DataValidationsBuildHelper.cs

Lines changed: 91 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@
2525
using DynamicExcelProvider.Enums;
2626
using DynamicExcelProvider.Mapper;
2727
using DynamicExcelProvider.Models.Request.Configuration.Property;
28+
using DynamicExcelProvider.Models.Request.Configuration.Template;
2829
using DynamicExcelProvider.WorkXCore.Extensions;
2930
using System;
3031
using System.Collections.Generic;
31-
using System.Diagnostics;
3232
using System.Linq;
3333
using System.Reflection;
3434

@@ -56,7 +56,7 @@ internal static class DataValidationsBuildHelper
5656
/// </returns>
5757
/// =================================================================================================
5858
internal static DataValidations BuildSheetDataValidations(
59-
ref IEnumerable<PropertyInfo> properties,
59+
ref IEnumerable<PropertyInfo> properties,
6060
ref IReadOnlyCollection<PropTranslateModel> outputProps)
6161
{
6262
try
@@ -96,25 +96,25 @@ internal static DataValidations BuildSheetDataValidations(
9696
dataValidation.ShowErrorMessage = new BooleanValue(true);
9797
}
9898

99-
if (validationAttribute.MinValue.IsNull().IsFalse())
99+
if (validationAttribute.MinValue.IsNotNull())
100100
{
101101
if (validationAttribute.ValidationType == ValidationType.Date)
102102
{
103103
var parseDate = Convert.ToDateTime(validationAttribute.MinValue);
104-
dataValidation.Formula1 = new Formula1($"DATE({parseDate.Year},{parseDate.Month},{parseDate.Day})");
104+
dataValidation.Formula1 = new Formula1("DATE({0},{1},{2})".FormatWith(parseDate.Year, parseDate.Month, parseDate.Day));
105105
}
106106
else
107107
dataValidation.Formula1 = new Formula1($"{validationAttribute.MinValue}");
108108
}
109109

110-
if (validationAttribute.MaxValue.IsNull().IsFalse())
110+
if (validationAttribute.MaxValue.IsNotNull())
111111
{
112112
if (validationAttribute.ValidationType == ValidationType.Date)
113113
{
114114
var parseDate = Convert.ToDateTime(validationAttribute.MaxValue);
115-
dataValidation.Formula2 = new Formula2($"DATE({parseDate.Year},{parseDate.Month},{parseDate.Day})");
115+
dataValidation.Formula2 = new Formula2("DATE({0},{1},{2})".FormatWith(parseDate.Year, parseDate.Month, parseDate.Day));
116116
}
117-
else
117+
else
118118
dataValidation.Formula2 = new Formula2($"{validationAttribute.MaxValue}");
119119
}
120120

@@ -130,14 +130,92 @@ internal static DataValidations BuildSheetDataValidations(
130130

131131
return dataValidations;
132132
}
133-
#if DEBUG
134-
catch (Exception ex)
133+
catch
135134
{
136-
Debug.WriteLine(ex);
137-
#else
138-
catch (Exception ex)
135+
return null;
136+
}
137+
}
138+
139+
/// -------------------------------------------------------------------------------------------------
140+
/// <summary>
141+
/// Builds sheet data validations.
142+
/// </summary>
143+
/// <param name="sheetValidations">[in,out] The sheet validations.</param>
144+
/// <returns>
145+
/// The DataValidations.
146+
/// </returns>
147+
/// =================================================================================================
148+
internal static DataValidations BuildSheetDataValidations(
149+
ref IEnumerable<TemplateDataValidation> sheetValidations)
150+
{
151+
try
152+
{
153+
var dataValidations = new DataValidations();
154+
155+
foreach (var validation in sheetValidations)
156+
{
157+
var sheetColumnLetter = SpreadsheetExtensions.GetExcelColumnName(validation.PropertyIndex).Response;
158+
159+
var dataValidation = new DataValidation
160+
{
161+
SequenceOfReferences = new ListValue<StringValue>
162+
{
163+
InnerText = $"{sheetColumnLetter}2:{sheetColumnLetter}1048576"
164+
},
165+
Type = new EnumValue<DataValidationValues>(EnumMapper.MapValidation(validation.ValidationType)),
166+
Operator = validation.ValidationType != ValidationType.List
167+
? new EnumValue<DataValidationOperatorValues>(EnumMapper.MapOperator(validation.OperatorType))
168+
: null,
169+
AllowBlank = new BooleanValue(validation.AllowEmpty.IsTrue())
170+
};
171+
172+
if (validation.PromptMessage.IsNullOrEmpty().IsFalse())
173+
{
174+
dataValidation.Prompt = validation.PromptMessage;
175+
dataValidation.ShowInputMessage = new BooleanValue(true);
176+
}
177+
178+
if (validation.ErrorMessage.IsNullOrEmpty().IsFalse())
179+
{
180+
dataValidation.Error = validation.ErrorMessage;
181+
dataValidation.ShowErrorMessage = new BooleanValue(true);
182+
}
183+
184+
if (validation.MinValue.IsNotNull())
185+
{
186+
if (validation.ValidationType == ValidationType.Date)
187+
{
188+
var parseDate = Convert.ToDateTime(validation.MinValue);
189+
dataValidation.Formula1 = new Formula1("DATE({0},{1},{2})".FormatWith(parseDate.Year, parseDate.Month, parseDate.Day));
190+
}
191+
else
192+
dataValidation.Formula1 = new Formula1($"{validation.MinValue}");
193+
}
194+
195+
if (validation.MaxValue.IsNotNull())
196+
{
197+
if (validation.ValidationType == ValidationType.Date)
198+
{
199+
var parseDate = Convert.ToDateTime(validation.MaxValue);
200+
dataValidation.Formula2 = new Formula2("DATE({0},{1},{2})".FormatWith(parseDate.Year, parseDate.Month, parseDate.Day));
201+
}
202+
else
203+
dataValidation.Formula2 = new Formula2($"{validation.MaxValue}");
204+
}
205+
206+
if (validation.AllowedValues.IsNullOrEmptyEnumerable().IsFalse())
207+
dataValidation.Formula1 = new Formula1($"\"{validation.AllowedValues.ListToString(",")}\"");
208+
209+
if (validation.ShowListInDropDown.IsTrue())
210+
dataValidation.ShowDropDown = new BooleanValue(true);
211+
212+
dataValidations.Append(dataValidation);
213+
}
214+
215+
return dataValidations;
216+
}
217+
catch
139218
{
140-
#endif
141219
return null;
142220
}
143221
}

src/DynamicExcelProvider/Helpers/DocGenerateParserHelper.cs

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -248,14 +248,14 @@ internal static IResult Generate(Stream stream, ExcelCollectionExportConfigurati
248248
/// </summary>
249249
/// <typeparam name="T">Generic type parameter.</typeparam>
250250
/// <param name="lcid">The lcid.</param>
251-
/// <param name="customOutFields">Custom user defined output/result fields.</param>
251+
/// <param name="customOutFields">(Optional) Custom user defined output/result fields.</param>
252252
/// <returns>
253253
/// The template.
254254
/// </returns>
255255
/// =================================================================================================
256256
internal static IResult<byte[]> GenerateTemplate<T>(
257257
int lcid,
258-
IReadOnlyCollection<string> customOutFields = null)
258+
IReadOnlyCollection<string> customOutFields = null)
259259
where T : class
260260
{
261261
const string sheetName = "Sheet1";
@@ -299,15 +299,15 @@ internal static IResult<byte[]> GenerateTemplate<T>(
299299
/// <typeparam name="T">Generic type parameter.</typeparam>
300300
/// <param name="stream">The stream.</param>
301301
/// <param name="lcid">The lcid.</param>
302-
/// <param name="customOutFields">Custom user defined output/result fields.</param>
302+
/// <param name="customOutFields">(Optional) Custom user defined output/result fields.</param>
303303
/// <returns>
304304
/// The template.
305305
/// </returns>
306306
/// =================================================================================================
307307
internal static IResult GenerateTemplate<T>(
308-
MemoryStream stream,
308+
MemoryStream stream,
309309
int lcid,
310-
IReadOnlyCollection<string> customOutFields = null)
310+
IReadOnlyCollection<string> customOutFields = null)
311311
where T : class
312312
{
313313
const string sheetName = "Sheet1";
@@ -341,5 +341,38 @@ internal static IResult GenerateTemplate<T>(
341341
? Result.Failure(document.Messages.FirstOrDefault()?.Message)
342342
: Result.Success();
343343
}
344+
345+
/// -------------------------------------------------------------------------------------------------
346+
/// <summary>
347+
/// Generates a template.
348+
/// </summary>
349+
/// <param name="stream">The stream.</param>
350+
/// <param name="configuration">The configuration.</param>
351+
/// <returns>
352+
/// The template.
353+
/// </returns>
354+
/// =================================================================================================
355+
internal static IResult GenerateTemplate(
356+
Stream stream,
357+
ExcelTemplateWriteConfiguration configuration)
358+
{
359+
var sheetName = configuration.SheetName.IfNullOrWhiteSpace("Sheet1");
360+
var wbDef = WorkbookParseBuildHelper.BuildAndParseToWorkbookDefinitionTemplate(
361+
sheetName,
362+
configuration.ColumnHeadings,
363+
configuration.SheetValidations,
364+
configuration.SheetValidations.IsNullOrEmptyEnumerable().IsFalse());
365+
if (wbDef.IsSuccess.IsFalse())
366+
return Result.Failure(wbDef.GetFirstMessage());
367+
368+
var document = SpreadsheetDocumentHelper.Instance.Write(
369+
stream: stream,
370+
workBook: wbDef.Response,
371+
appendSheetValidations: true);
372+
373+
return document.IsSuccess.IsFalse()
374+
? Result.Failure(document.Messages.FirstOrDefault()?.Message)
375+
: Result.Success();
376+
}
344377
}
345378
}

0 commit comments

Comments
 (0)