From 7fe8020125fecb4173b9f88a5daed949f286167b Mon Sep 17 00:00:00 2001 From: Dom Schira Date: Mon, 21 Jun 2021 16:03:19 -0700 Subject: [PATCH 01/12] Okay have an idea how to consolidate things --- ExcelExtensions/Interfaces/IExtensions.cs | 12 +-- .../Interfaces/Import/Parse/ITableParser.cs | 4 +- ExcelExtensions/Models/Column.cs | 17 ++-- .../Models/ExcelExtensionsColumnAttribute.cs | 44 +++++++++++ .../Models/ImportColumnTemplate.cs | 26 +++--- ExcelExtensions/Models/ParseException.cs | 2 +- ExcelExtensions/Providers/Export/Exporter.cs | 8 +- ExcelExtensions/Providers/Extensions.cs | 20 ++--- .../Providers/Import/ImportMapFactory.cs | 79 +++++++++++++++++++ .../Providers/Import/Parse/TableParser.cs | 31 ++++---- .../Providers/ParseTableTest.cs | 24 +++--- WebApplication/Providers/SampleProvider.cs | 40 +++++----- 12 files changed, 219 insertions(+), 88 deletions(-) create mode 100644 ExcelExtensions/Models/ExcelExtensionsColumnAttribute.cs create mode 100644 ExcelExtensions/Providers/Import/ImportMapFactory.cs diff --git a/ExcelExtensions/Interfaces/IExtensions.cs b/ExcelExtensions/Interfaces/IExtensions.cs index 2f526ea..18f439c 100644 --- a/ExcelExtensions/Interfaces/IExtensions.cs +++ b/ExcelExtensions/Interfaces/IExtensions.cs @@ -104,12 +104,12 @@ public interface IExtensions /// - KeyValuePair LogDeveloperException(string worksheetName, ImportColumnTemplate displayName, string cellAddress, string message, string modelPropertyName); - KeyValuePair LogDeveloperException(string worksheetName, ImportColumnTemplate displayName, string cellAddress, int rowNumber, string message); - KeyValuePair LogNullReferenceException(string worksheetName, ImportColumnTemplate displayName, string cellAddress, string modelPropertyName); - KeyValuePair LogNullReferenceException(string worksheetName, ImportColumnTemplate displayName, string cellAddress, int rowNumber); - KeyValuePair LogCellException(string worksheetName, ImportColumnTemplate displayName, string cellAddress, int rowNumber); - KeyValuePair LogCellException(string worksheetName, ImportColumnTemplate displayName, string cellAddress, string modelPropertyName); + KeyValuePair LogDeveloperException(string worksheetName, ImportColumn displayName, string cellAddress, string message, string modelPropertyName); + KeyValuePair LogDeveloperException(string worksheetName, ImportColumn displayName, string cellAddress, int rowNumber, string message); + KeyValuePair LogNullReferenceException(string worksheetName, ImportColumn displayName, string cellAddress, string modelPropertyName); + KeyValuePair LogNullReferenceException(string worksheetName, ImportColumn displayName, string cellAddress, int rowNumber); + KeyValuePair LogCellException(string worksheetName, ImportColumn displayName, string cellAddress, int rowNumber); + KeyValuePair LogCellException(string worksheetName, ImportColumn displayName, string cellAddress, string modelPropertyName); } } \ No newline at end of file diff --git a/ExcelExtensions/Interfaces/Import/Parse/ITableParser.cs b/ExcelExtensions/Interfaces/Import/Parse/ITableParser.cs index f89f28f..b0ec620 100644 --- a/ExcelExtensions/Interfaces/Import/Parse/ITableParser.cs +++ b/ExcelExtensions/Interfaces/Import/Parse/ITableParser.cs @@ -12,7 +12,7 @@ namespace ExcelExtensions.Interfaces.Import.Parse /// Object the excel data is being mapped to. public interface ITableParser { - ParsedTable ScanForColumnsAndParseTable(List columns, ExcelWorksheet workSheet, int headerRowNumber = 1, int maxScanHeaderRowThreashold = 100); - ParsedTable ParseTable(List columns, ExcelWorksheet workSheet, int headerRowNumber = 1); + ParsedTable ScanForColumnsAndParseTable(List columns, ExcelWorksheet workSheet, int headerRowNumber = 1, int maxScanHeaderRowThreashold = 100); + ParsedTable ParseTable(List columns, ExcelWorksheet workSheet, int headerRowNumber = 1); } } diff --git a/ExcelExtensions/Models/Column.cs b/ExcelExtensions/Models/Column.cs index 7df0609..4b06602 100644 --- a/ExcelExtensions/Models/Column.cs +++ b/ExcelExtensions/Models/Column.cs @@ -13,8 +13,9 @@ public class Column { /// /// Represents the location/letter of the excel column. Ex "C" + /// Used for exports and import where we know where to look and are not parsing for new col locations /// - public string ColumnLetter { get; set; } + public string ExportColumnLetter { get; set; } /// /// Represents property name for the mapping object. /// @@ -22,7 +23,7 @@ public class Column /// /// Represents the human readable column header name/title /// - public string HeaderTitle { get; set; } + public string TableHeaderTitle { get; set; } /// /// Represents the format type for the excel object /// @@ -38,9 +39,9 @@ public Column() } public Column(string modelPropertyName, string headerTitle, string columnLetter, FormatType format, int? decimalPrecision = null) { - ColumnLetter = columnLetter; + ExportColumnLetter = columnLetter; ModelProperty = modelPropertyName; - HeaderTitle = headerTitle; + TableHeaderTitle = headerTitle; Format = format; DecimalPrecision = decimalPrecision; } @@ -49,19 +50,19 @@ public Column(IExtensions _excelExtensions, Type modelType, string modelProperty _excelExtensions.GetExportModelPropertyNameAndDisplayName(modelType, modelPropertyName, out string textTitle); if (columnLetter != null) { - ColumnLetter = columnLetter; + ExportColumnLetter = columnLetter; } ModelProperty = modelPropertyName; - HeaderTitle = textTitle; + TableHeaderTitle = textTitle; Format = format; DecimalPrecision = decimalPrecision; } public Column(IExtensions _excelExtensions, Type modelType, string modelPropertyName, FormatType format, int columnLetterAsInt, int? decimalPrecision = null) { _excelExtensions.GetExportModelPropertyNameAndDisplayName(modelType, modelPropertyName, out string textTitle); - ColumnLetter = _excelExtensions.GetColumnLetter(columnLetterAsInt); + ExportColumnLetter = _excelExtensions.GetColumnLetter(columnLetterAsInt); ModelProperty = modelPropertyName; - HeaderTitle = textTitle; + TableHeaderTitle = textTitle; Format = format; DecimalPrecision = decimalPrecision; } diff --git a/ExcelExtensions/Models/ExcelExtensionsColumnAttribute.cs b/ExcelExtensions/Models/ExcelExtensionsColumnAttribute.cs new file mode 100644 index 0000000..a9ae891 --- /dev/null +++ b/ExcelExtensions/Models/ExcelExtensionsColumnAttribute.cs @@ -0,0 +1,44 @@ +// Copyright (c) Dominic Schira . All Rights Reserved. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static ExcelExtensions.Enums.Enums; + +namespace ExcelExtensions.Models +{ + [AttributeUsage(AttributeTargets.Property, Inherited = false)] + public class ExcelExtensionsColumnAttribute : Attribute + { + /// + /// Represent the list of options for the header name + /// + public List ImportColumnTitleOptions { get; set; } + + /// + /// If required then if not then warning + /// + public bool? IsRequired { get; set; } + + //Might be albe to depricate this + /// + /// Represents the format type for the excel object + /// + public FormatType Format { get; set; } + /// + /// Represents the number of decimal places in the output for export + /// + public int? DecimalPrecision { get; set; } + + public string? ExportColumnLetter { get; set; } + + public int? ExportColumnNumber { get; set; } + + public string? ImportColumnLetter { get; set; } + + public int? ImportColumnNumber { get; set; } + + } +} diff --git a/ExcelExtensions/Models/ImportColumnTemplate.cs b/ExcelExtensions/Models/ImportColumnTemplate.cs index be0c9f8..9b25667 100644 --- a/ExcelExtensions/Models/ImportColumnTemplate.cs +++ b/ExcelExtensions/Models/ImportColumnTemplate.cs @@ -6,7 +6,8 @@ namespace ExcelExtensions.Models { - public class ImportColumnTemplate + //TODO: replace with data attributes + public class ImportColumn { /// /// Represent the list of options for the header name @@ -17,7 +18,7 @@ public class ImportColumnTemplate /// public bool IsRequired { get; set; } public Column Column { get; set; } - public ImportColumnTemplate() + public ImportColumn() { } @@ -27,29 +28,34 @@ public ImportColumnTemplate() /// /// /// Optional names to search for - public ImportColumnTemplate(Column column, bool required, List columnOptions = null) + public ImportColumn(Column column, bool required, List columnOptions = null) { ColumnHeaderOptions = columnOptions ?? new List(); - ColumnHeaderOptions.Add(column.HeaderTitle); + ColumnHeaderOptions.Add(column.TableHeaderTitle); IsRequired = required; Column = column; } } - public class ImportColumnWithCellAddress : ImportColumnTemplate + /// + /// This class has our number populated so that if we have a letter provided we get to have a number + /// + public class ImportColumnWithCellAddress : ImportColumn { - public int ColumnNumber { get; set; } - public string DisplayColumnHeaderNames => ColumnHeaderOptions.Aggregate((a, x) => a + ", " + x); - + /// + /// used as a pointer for where we are importing and saved if we are looking for a column that doesn't have a letter + /// This will override the letter and use the number for data + /// + public int ImportColumnNumber { get; set; } public ImportColumnWithCellAddress() : base() { } - public ImportColumnWithCellAddress(IExtensions excelExtensions, ImportColumnTemplate template) : base(template.Column, template.IsRequired, template.ColumnHeaderOptions) + public ImportColumnWithCellAddress(IExtensions excelExtensions, ImportColumn template) : base(template.Column, template.IsRequired, template.ColumnHeaderOptions) { - ColumnNumber = template.Column.ColumnLetter == null ? 0 : excelExtensions.GetColumnNumber(template.Column.ColumnLetter); + ImportColumnNumber = template.Column.ExportColumnLetter == null ? 0 : excelExtensions.GetColumnNumber(template.Column.ExportColumnLetter); } } diff --git a/ExcelExtensions/Models/ParseException.cs b/ExcelExtensions/Models/ParseException.cs index af8d4bd..4662925 100644 --- a/ExcelExtensions/Models/ParseException.cs +++ b/ExcelExtensions/Models/ParseException.cs @@ -72,7 +72,7 @@ public ParseException(string sheetName, Column column) : this (sheetName) //ColumnHeader = column.ColumnHeader; //todo FormatType = column.Format; } - public ParseException(string sheetName, ImportColumnTemplate column) : this (sheetName, column.Column) + public ParseException(string sheetName, ImportColumn column) : this (sheetName, column.Column) { Severity = (column.IsRequired) ? ParseExceptionSeverity.Error : ParseExceptionSeverity.Warning; } diff --git a/ExcelExtensions/Providers/Export/Exporter.cs b/ExcelExtensions/Providers/Export/Exporter.cs index 493f396..4e27bce 100644 --- a/ExcelExtensions/Providers/Export/Exporter.cs +++ b/ExcelExtensions/Providers/Export/Exporter.cs @@ -49,7 +49,7 @@ public void ExportColumns(ref ExcelWorksheet sheet, List rows, List public void FormatColumn(Column column, ref ExcelWorksheet sheet) { - FormatColumn(ref sheet, column.ColumnLetter, column.Format, column.DecimalPrecision); + FormatColumn(ref sheet, column.ExportColumnLetter, column.Format, column.DecimalPrecision); } /// public void FormatColumn(ref ExcelWorksheet sheet, string column, FormatType formatter, int? decimalPrecision = null) diff --git a/ExcelExtensions/Providers/Extensions.cs b/ExcelExtensions/Providers/Extensions.cs index a640557..59afdeb 100644 --- a/ExcelExtensions/Providers/Extensions.cs +++ b/ExcelExtensions/Providers/Extensions.cs @@ -18,20 +18,20 @@ namespace ExcelExtensions.Providers public class Extensions : IExtensions { #region developer exceptions - public KeyValuePair LogDeveloperException(string worksheetName, ImportColumnTemplate importColumn, string cellAddress, string message, string modelPropertyName) + public KeyValuePair LogDeveloperException(string worksheetName, ImportColumn importColumn, string cellAddress, string message, string modelPropertyName) { ParseException parseException = LogDeveloperExceptionParseException(worksheetName, importColumn, cellAddress, message); return new KeyValuePair(modelPropertyName, parseException); } - public KeyValuePair LogDeveloperException(string worksheetName, ImportColumnTemplate importColumn, string cellAddress, int rowNumber, string message) + public KeyValuePair LogDeveloperException(string worksheetName, ImportColumn importColumn, string cellAddress, int rowNumber, string message) { ParseException parseException = LogDeveloperExceptionParseException(worksheetName, importColumn, cellAddress, message); return new KeyValuePair(rowNumber, parseException); } - private ParseException LogDeveloperExceptionParseException(string worksheetName, ImportColumnTemplate importColumn, string cellAddress, string exeptionMessage) + private ParseException LogDeveloperExceptionParseException(string worksheetName, ImportColumn importColumn, string cellAddress, string exeptionMessage) { //ParseException parseException = new(worksheetName, displayName, cellAddress, null, "An error occurred when trying to set the property info. The error is: " + message) ParseException parseException = new(worksheetName, importColumn.Column) @@ -45,21 +45,21 @@ private ParseException LogDeveloperExceptionParseException(string worksheetName, return parseException; } - public KeyValuePair LogNullReferenceException(string worksheetName, ImportColumnTemplate displayName, string cellAddress, string modelPropertyName) + public KeyValuePair LogNullReferenceException(string worksheetName, ImportColumn displayName, string cellAddress, string modelPropertyName) { ParseException parseException = LogNullReferenceExceptionParseException(worksheetName, displayName, cellAddress); return new KeyValuePair(modelPropertyName, parseException); } - public KeyValuePair LogNullReferenceException(string worksheetName, ImportColumnTemplate displayName, string cellAddress, int rowNumber) + public KeyValuePair LogNullReferenceException(string worksheetName, ImportColumn displayName, string cellAddress, int rowNumber) { ParseException parseException = LogNullReferenceExceptionParseException(worksheetName, displayName, cellAddress); return new KeyValuePair(rowNumber, parseException); } - private ParseException LogNullReferenceExceptionParseException(string worksheetName, ImportColumnTemplate column, string cellAddress) + private ParseException LogNullReferenceExceptionParseException(string worksheetName, ImportColumn column, string cellAddress) { ParseException parseException = new(worksheetName, column) { @@ -71,21 +71,21 @@ private ParseException LogNullReferenceExceptionParseException(string worksheetN return parseException; } - public KeyValuePair LogCellException(string worksheetName, ImportColumnTemplate displayName, string cellAddress, string modelPropertyName) + public KeyValuePair LogCellException(string worksheetName, ImportColumn displayName, string cellAddress, string modelPropertyName) { ParseException parseException = LogCellExceptionParseException(worksheetName, displayName, cellAddress); return new KeyValuePair(modelPropertyName, parseException); } - public KeyValuePair LogCellException(string worksheetName, ImportColumnTemplate displayName, string cellAddress, int rowNumber) + public KeyValuePair LogCellException(string worksheetName, ImportColumn displayName, string cellAddress, int rowNumber) { ParseException parseException = LogCellExceptionParseException(worksheetName, displayName, cellAddress); return new KeyValuePair(rowNumber, parseException); } - private ParseException LogCellExceptionParseException(string worksheetName, ImportColumnTemplate column, string cellAddress) + private ParseException LogCellExceptionParseException(string worksheetName, ImportColumn column, string cellAddress) { ParseException parseException = new(worksheetName, column) { @@ -197,7 +197,7 @@ public int FindMaxRow(List cells) /// public int FindMaxColumn(List columns) - => columns.Select(column => GetColumnNumber(column.ColumnLetter)).Max(); + => columns.Select(column => GetColumnNumber(column.ExportColumnLetter)).Max(); /// public string AddDecimalPlacesToFormat(Column column, string noDecimals) diff --git a/ExcelExtensions/Providers/Import/ImportMapFactory.cs b/ExcelExtensions/Providers/Import/ImportMapFactory.cs new file mode 100644 index 0000000..400f7f5 --- /dev/null +++ b/ExcelExtensions/Providers/Import/ImportMapFactory.cs @@ -0,0 +1,79 @@ +// Copyright (c) Dominic Schira . All Rights Reserved. + +using ExcelExtensions.Interfaces; +using ExcelExtensions.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using static ExcelExtensions.Enums.Enums; + +namespace ExcelExtensions.Providers.Import +{ + public class ImportMapFactory + { + private readonly IExtensions _excelExtensions; + + public ImportMapFactory(IExtensions excelExtensions) + { + _excelExtensions = excelExtensions; + + } + + + public List MapObjectToImportColumns(Type modelType, FormatType formatType = FormatType.String, int startColumnNumber = 1) + { + //If you give me an int you know where it is, or if you give me a letter you know where it is + + //make methods + + //1st sets up just for imports in case you need to make tweaks (would have to know the letters or numbers) + + + //2nd set up just for exports (would have to know the letters or numbers) + + //3rd, option where you really don't care where you export data because it is in order how you set up your model + + + //Could possible make Column and protected class and make ImportColumn and ExportColum then a class that encapsulates both for a LazyColumn + + int currentColumnNumber = startColumnNumber; + List excelColumnDefinitionArray = new(); + + foreach (PropertyInfo item in modelType.GetProperties()) + { + //read the display name attirube + string modelPropertyName = _excelExtensions.GetExportModelPropertyNameAndDisplayName(modelType, item.Name, out string textTitle); + + ExcelExtensionsColumnAttribute attribute = item.GetCustomAttribute(); + + //Give the default format if not avail be + FormatType format = attribute?.Format ?? formatType; + + //TODO: theses all below need to be re though with a new idea of separating the column types out + string letter = attribute?.ExportColumnLetter ?? _excelExtensions.GetColumnLetter(currentColumnNumber); + bool required = attribute?.IsRequired ?? true; // + List importKeys = attribute?.ImportColumnTitleOptions ?? new List() { modelPropertyName, textTitle }; + + excelColumnDefinitionArray.Add(new ImportColumnWithCellAddress() + { + //If already know our column letter lets use that. + ImportColumnNumber = attribute?.ExportColumnLetter == null ? 0 : _excelExtensions.GetColumnNumber(attribute.ExportColumnLetter), + Column = new Column(modelPropertyName, + textTitle, + letter, + format, + attribute?.DecimalPrecision), + ColumnHeaderOptions = importKeys, + IsRequired = required + }); + //next column + currentColumnNumber++; + } + + return excelColumnDefinitionArray; + } + } +} diff --git a/ExcelExtensions/Providers/Import/Parse/TableParser.cs b/ExcelExtensions/Providers/Import/Parse/TableParser.cs index af4d880..fd850ba 100644 --- a/ExcelExtensions/Providers/Import/Parse/TableParser.cs +++ b/ExcelExtensions/Providers/Import/Parse/TableParser.cs @@ -33,7 +33,7 @@ public TableParser(IExtensions excelExtensions, IParser parser) _parseResults = new ParsedTable(); _requiredFieldMissingMessages = new List(); } - public ParsedTable ScanForColumnsAndParseTable(List columns, ExcelWorksheet workSheet, int headerRowNumber = 1, int maxScanHeaderRowThreashold = 100) + public ParsedTable ScanForColumnsAndParseTable(List columns, ExcelWorksheet workSheet, int headerRowNumber = 1, int maxScanHeaderRowThreashold = 100) { if (_excelExtensions is null) { @@ -55,7 +55,7 @@ public ParsedTable ScanForColumnsAndParseTable(List col return ParseRows(columnsWithCellAddresses, workSheet, headerRowNumber); } - public ParsedTable ParseTable(List columns, ExcelWorksheet workSheet, int headerRowNumber = 1) + public ParsedTable ParseTable(List columns, ExcelWorksheet workSheet, int headerRowNumber = 1) { if (_excelExtensions is null) { @@ -64,14 +64,14 @@ public ParsedTable ParseTable(List columns, ExcelWorksh List columnsWithCellAddresses = CheckForMissingColumnNumbersInImportColumnTemplates(columns); - if (columnsWithCellAddresses.Any(x => x.IsRequired && x.ColumnNumber <= 0)) + if (columnsWithCellAddresses.Any(x => x.IsRequired && x.ImportColumnNumber <= 0)) { throw new ArgumentOutOfRangeException(nameof(columns), "All ColumnTemplate's must have a ColumnNumber. If the ColumnNumber is unknown use the ScanForColumnsAndParseTable method."); } //Assign required columns foreach (ImportColumnWithCellAddress col in columnsWithCellAddresses.Where(x => x.IsRequired)) { - _requiredFieldsColumnLocations.Add(col.Column.ColumnLetter); + _requiredFieldsColumnLocations.Add(col.Column.ExportColumnLetter); } //Parse each row @@ -95,12 +95,13 @@ private ParsedTable ParseRows(List columnsWithCe foreach (ImportColumnWithCellAddress coltemplate in columnsWithCellAddresses) { - if (coltemplate.ColumnNumber < 1 || coltemplate.ColumnNumber > workSheet.Dimension.End.Column) + //If its at defualt(0) or we have reached the end of the sheet bail out + if (coltemplate.ImportColumnNumber < 1 || coltemplate.ImportColumnNumber > workSheet.Dimension.End.Column) { continue; } - ExcelRange cell = workSheet.Cells[rowNumber, coltemplate.ColumnNumber]; + ExcelRange cell = workSheet.Cells[rowNumber, coltemplate.ImportColumnNumber]; ParseCell(workSheet, rowNumber, coltemplate, cell); } @@ -142,10 +143,10 @@ private ParsedTable ParseRows(List columnsWithCe /// Get the cell address using the extension from the data the user provided in the import map /// /// - private List CheckForMissingColumnNumbersInImportColumnTemplates(List columns) + private List CheckForMissingColumnNumbersInImportColumnTemplates(List columns) { List columnsWithCellAddresses = new(); - foreach (ImportColumnTemplate item in columns) + foreach (ImportColumn item in columns) { columnsWithCellAddresses.Add(new ImportColumnWithCellAddress(_excelExtensions, item)); } @@ -204,7 +205,7 @@ private void ScanForHeaderRow(List columns, ref Exc /// /// /// - private bool CheckMissingScannedColumns(int headerRowId, int maxScanHeaderRowThreashold, int rowScanCount, List columns) + private bool CheckMissingScannedColumns(int headerRowId, int maxScanHeaderRowThreashold, int rowScanCount, List columns) { if (rowScanCount >= maxScanHeaderRowThreashold && _requiredFieldMissingMessages.Count == columns.Where(x => x.IsRequired).Count()) @@ -258,12 +259,12 @@ private void FindColumnNamesAndCheckRequiredColumns(List x.Equals(firstRowCell.Text, StringComparison.OrdinalIgnoreCase))) { - coltemplate.ColumnNumber = firstRowCell.Start.Column; + coltemplate.ImportColumnNumber = firstRowCell.Start.Column; continue; } } - if (coltemplate.IsRequired && coltemplate.ColumnNumber == 0) + if (coltemplate.IsRequired && coltemplate.ImportColumnNumber == 0) { ParseException parseException = new(workSheet.Name, coltemplate.Column) @@ -274,7 +275,7 @@ private void FindColumnNamesAndCheckRequiredColumns(List(headerRowId, parseException)); } - else if (coltemplate.ColumnNumber == 0 && coltemplate.IsRequired == false) + else if (coltemplate.ImportColumnNumber == 0 && coltemplate.IsRequired == false) { ParseException parseException = new(workSheet.Name, coltemplate.Column) { @@ -288,7 +289,7 @@ private void FindColumnNamesAndCheckRequiredColumns(List /// /// Will throw errors. disable them when debugging through this dll file. - private void ParseCell(ExcelWorksheet workSheet, int rowNumber, ImportColumnTemplate coltemplate, ExcelRange cell) + private void ParseCell(ExcelWorksheet workSheet, int rowNumber, ImportColumn coltemplate, ExcelRange cell) { switch (coltemplate.Column.Format) { @@ -562,7 +563,7 @@ private void ParseCell(ExcelWorksheet workSheet, int rowNumber, ImportColumnTemp /// /// /// - private void SetValue(ExcelWorksheet workSheet, int rowNumber, ImportColumnTemplate coltemplate, ExcelRange cell, object value) + private void SetValue(ExcelWorksheet workSheet, int rowNumber, ImportColumn coltemplate, ExcelRange cell, object value) { try { diff --git a/ExcelExtensionsTests/Providers/ParseTableTest.cs b/ExcelExtensionsTests/Providers/ParseTableTest.cs index c18fc18..ee8698e 100644 --- a/ExcelExtensionsTests/Providers/ParseTableTest.cs +++ b/ExcelExtensionsTests/Providers/ParseTableTest.cs @@ -67,15 +67,15 @@ private void CreateTestFile(ref ExcelWorksheet sheet, List GetScannedColumns() + private List GetScannedColumns() { Type type = typeof(ParseTableTestBaseModel); - return new List() + return new List() { - new ImportColumnTemplate(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.RequiredText), FormatType.String), true), - new ImportColumnTemplate(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.Date), FormatType.Date), true), - new ImportColumnTemplate(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.Decimal), FormatType.Decimal), true), - new ImportColumnTemplate(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.OptionalText), FormatType.String), false), + new ImportColumn(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.RequiredText), FormatType.String), true), + new ImportColumn(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.Date), FormatType.Date), true), + new ImportColumn(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.Decimal), FormatType.Decimal), true), + new ImportColumn(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.OptionalText), FormatType.String), false), }; } /// @@ -83,17 +83,17 @@ private List GetScannedColumns() /// /// /// - private List GetKnownColumns(int colStart) + private List GetKnownColumns(int colStart) { int i = colStart; Type type = typeof(ParseTableTestBaseModel); - return new List() + return new List() { - new ImportColumnTemplate(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.RequiredText), FormatType.String, i++), true), - new ImportColumnTemplate(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.Date), FormatType.Date, i++), true), - new ImportColumnTemplate(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.Decimal), FormatType.Decimal, i++), true), - new ImportColumnTemplate(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.OptionalText), FormatType.String, i++), false), + new ImportColumn(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.RequiredText), FormatType.String, i++), true), + new ImportColumn(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.Date), FormatType.Date, i++), true), + new ImportColumn(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.Decimal), FormatType.Decimal, i++), true), + new ImportColumn(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.OptionalText), FormatType.String, i++), false), }; } diff --git a/WebApplication/Providers/SampleProvider.cs b/WebApplication/Providers/SampleProvider.cs index e7edc9e..e8a497e 100644 --- a/WebApplication/Providers/SampleProvider.cs +++ b/WebApplication/Providers/SampleProvider.cs @@ -79,32 +79,32 @@ public Dictionary ScanForColumnsAndParseTable(IFormFile f /// Sets the requiredments for import and our model property. /// /// - private List GetTableColumnTemplates() + private List GetTableColumnTemplates() { //TODO USE REFLECTION https://github.com/domshyra/ExcelExtensions/issues/15 List cols = SampleTableColumns(); - return new List() + return new List() { // Col Req? - new ImportColumnTemplate(GetColumn(cols, nameof(SampleTableModel.Text)), true), - new ImportColumnTemplate(GetColumn(cols, nameof(SampleTableModel.Date)), true), - new ImportColumnTemplate(GetColumn(cols, nameof(SampleTableModel.DateAsText)), true), - new ImportColumnTemplate(GetColumn(cols, nameof(SampleTableModel.DateAsGeneral)), false), - new ImportColumnTemplate(GetColumn(cols, nameof(SampleTableModel.Duration)), false), - new ImportColumnTemplate(GetColumn(cols, nameof(SampleTableModel.Percent)), true), - new ImportColumnTemplate(GetColumn(cols, nameof(SampleTableModel.PercentAsText)), false), - new ImportColumnTemplate(GetColumn(cols, nameof(SampleTableModel.PercentAsNumber)), false), - new ImportColumnTemplate(GetColumn(cols, nameof(SampleTableModel.BoolAsYESNO)), false), - new ImportColumnTemplate(GetColumn(cols, nameof(SampleTableModel.BoolAsTrueFalse)), false), - new ImportColumnTemplate(GetColumn(cols, nameof(SampleTableModel.BoolAs10)), false), - new ImportColumnTemplate(GetColumn(cols, nameof(SampleTableModel.Currency)), false), - new ImportColumnTemplate(GetColumn(cols, nameof(SampleTableModel.CurrencyAsText)), false), - new ImportColumnTemplate(GetColumn(cols, nameof(SampleTableModel.CurrencyAsGeneral)), false), - new ImportColumnTemplate(GetColumn(cols, nameof(SampleTableModel.Decimal)), false), - new ImportColumnTemplate(GetColumn(cols, nameof(SampleTableModel.DecimalAsText)), false), - new ImportColumnTemplate(GetColumn(cols, nameof(SampleTableModel.RequiredText)), true), - new ImportColumnTemplate(GetColumn(cols, nameof(SampleTableModel.OptionalText)), false), + new ImportColumn(GetColumn(cols, nameof(SampleTableModel.Text)), true), + new ImportColumn(GetColumn(cols, nameof(SampleTableModel.Date)), true), + new ImportColumn(GetColumn(cols, nameof(SampleTableModel.DateAsText)), true), + new ImportColumn(GetColumn(cols, nameof(SampleTableModel.DateAsGeneral)), false), + new ImportColumn(GetColumn(cols, nameof(SampleTableModel.Duration)), false), + new ImportColumn(GetColumn(cols, nameof(SampleTableModel.Percent)), true), + new ImportColumn(GetColumn(cols, nameof(SampleTableModel.PercentAsText)), false), + new ImportColumn(GetColumn(cols, nameof(SampleTableModel.PercentAsNumber)), false), + new ImportColumn(GetColumn(cols, nameof(SampleTableModel.BoolAsYESNO)), false), + new ImportColumn(GetColumn(cols, nameof(SampleTableModel.BoolAsTrueFalse)), false), + new ImportColumn(GetColumn(cols, nameof(SampleTableModel.BoolAs10)), false), + new ImportColumn(GetColumn(cols, nameof(SampleTableModel.Currency)), false), + new ImportColumn(GetColumn(cols, nameof(SampleTableModel.CurrencyAsText)), false), + new ImportColumn(GetColumn(cols, nameof(SampleTableModel.CurrencyAsGeneral)), false), + new ImportColumn(GetColumn(cols, nameof(SampleTableModel.Decimal)), false), + new ImportColumn(GetColumn(cols, nameof(SampleTableModel.DecimalAsText)), false), + new ImportColumn(GetColumn(cols, nameof(SampleTableModel.RequiredText)), true), + new ImportColumn(GetColumn(cols, nameof(SampleTableModel.OptionalText)), false), //new ImportColumnTemplate(GetColumn(cols, nameof(SampleTableModel.ListOfStrings)), false), //new ImportColumnTemplate(GetColumn(cols, nameof(SampleTableModel.ListOfStrings)), false), //new ImportColumnTemplate(GetColumn(cols, nameof(SampleTableModel.ListOfStrings)), false), From cfac1795bd7aac80b01a6a929b460c970ef9aec2 Mon Sep 17 00:00:00 2001 From: Dom Schira Date: Mon, 21 Jun 2021 17:15:38 -0700 Subject: [PATCH 02/12] Moving files to maybe make more sense of the two imports --- .../Interfaces/Export/IExporter.cs | 6 +- ExcelExtensions/Interfaces/IExtensions.cs | 12 +-- .../Interfaces/Import/Parse/ITableParser.cs | 4 +- ExcelExtensions/Models/Column.cs | 38 +-------- ExcelExtensions/Models/ColumnWithSeverity.cs | 29 +++++++ .../Models/ExcelExtensionsColumnAttribute.cs | 2 + ExcelExtensions/Models/ExportColumn.cs | 72 +++++++++++++++++ .../Models/ImportColumnTemplate.cs | 63 --------------- ExcelExtensions/Models/LazyColumn.cs | 20 +++++ ExcelExtensions/Models/ParseException.cs | 2 +- .../Models/UninformedImportColumn.cs | 80 +++++++++++++++++++ ExcelExtensions/Providers/Export/Exporter.cs | 65 +++++++++------ ExcelExtensions/Providers/Extensions.cs | 18 ++--- .../Providers/Import/ImportMapFactory.cs | 8 +- .../Providers/Import/Parse/TableParser.cs | 56 +++++++------ .../Providers/ParseTableTest.cs | 44 +++++----- WebApplication/Providers/SampleProvider.cs | 42 +++++----- 17 files changed, 349 insertions(+), 212 deletions(-) create mode 100644 ExcelExtensions/Models/ColumnWithSeverity.cs create mode 100644 ExcelExtensions/Models/ExportColumn.cs delete mode 100644 ExcelExtensions/Models/ImportColumnTemplate.cs create mode 100644 ExcelExtensions/Models/LazyColumn.cs create mode 100644 ExcelExtensions/Models/UninformedImportColumn.cs diff --git a/ExcelExtensions/Interfaces/Export/IExporter.cs b/ExcelExtensions/Interfaces/Export/IExporter.cs index 479b204..dd7471c 100644 --- a/ExcelExtensions/Interfaces/Export/IExporter.cs +++ b/ExcelExtensions/Interfaces/Export/IExporter.cs @@ -42,10 +42,11 @@ public interface IExporter /// Format the column of an /// /// - /// + /// /// /// - void FormatColumn(ref ExcelWorksheet sheet, string column, FormatType formatter, int? decimalPrecision = null); + void FormatColumn(ref ExcelWorksheet sheet, int columnNumber, FormatType formatter, int? decimalPrecision = null); + void FormatColumn(ref ExcelWorksheet sheet, string columnLetter, FormatType formatter, int? decimalPrecision = null); /// /// Format the column range of an /// @@ -55,6 +56,7 @@ public interface IExporter /// /// void FormatColumnRange(ExcelWorksheet itemcodeSheet, string startColumn, string endColumn, FormatType format, int? decimalPrecision = null); + void FormatColumnRange(ExcelWorksheet itemcodeSheet, int startColumn, int endColumn, FormatType format, int? decimalPrecision = null); /// /// Style the table header row by the max column in columns of an /// diff --git a/ExcelExtensions/Interfaces/IExtensions.cs b/ExcelExtensions/Interfaces/IExtensions.cs index 18f439c..d302754 100644 --- a/ExcelExtensions/Interfaces/IExtensions.cs +++ b/ExcelExtensions/Interfaces/IExtensions.cs @@ -104,12 +104,12 @@ public interface IExtensions /// - KeyValuePair LogDeveloperException(string worksheetName, ImportColumn displayName, string cellAddress, string message, string modelPropertyName); - KeyValuePair LogDeveloperException(string worksheetName, ImportColumn displayName, string cellAddress, int rowNumber, string message); - KeyValuePair LogNullReferenceException(string worksheetName, ImportColumn displayName, string cellAddress, string modelPropertyName); - KeyValuePair LogNullReferenceException(string worksheetName, ImportColumn displayName, string cellAddress, int rowNumber); - KeyValuePair LogCellException(string worksheetName, ImportColumn displayName, string cellAddress, int rowNumber); - KeyValuePair LogCellException(string worksheetName, ImportColumn displayName, string cellAddress, string modelPropertyName); + KeyValuePair LogDeveloperException(string worksheetName, UninformedImportColumn displayName, string cellAddress, string message, string modelPropertyName); + KeyValuePair LogDeveloperException(string worksheetName, UninformedImportColumn displayName, string cellAddress, int rowNumber, string message); + KeyValuePair LogNullReferenceException(string worksheetName, UninformedImportColumn displayName, string cellAddress, string modelPropertyName); + KeyValuePair LogNullReferenceException(string worksheetName, UninformedImportColumn displayName, string cellAddress, int rowNumber); + KeyValuePair LogCellException(string worksheetName, UninformedImportColumn displayName, string cellAddress, int rowNumber); + KeyValuePair LogCellException(string worksheetName, UninformedImportColumn displayName, string cellAddress, string modelPropertyName); } } \ No newline at end of file diff --git a/ExcelExtensions/Interfaces/Import/Parse/ITableParser.cs b/ExcelExtensions/Interfaces/Import/Parse/ITableParser.cs index b0ec620..524d22e 100644 --- a/ExcelExtensions/Interfaces/Import/Parse/ITableParser.cs +++ b/ExcelExtensions/Interfaces/Import/Parse/ITableParser.cs @@ -12,7 +12,7 @@ namespace ExcelExtensions.Interfaces.Import.Parse /// Object the excel data is being mapped to. public interface ITableParser { - ParsedTable ScanForColumnsAndParseTable(List columns, ExcelWorksheet workSheet, int headerRowNumber = 1, int maxScanHeaderRowThreashold = 100); - ParsedTable ParseTable(List columns, ExcelWorksheet workSheet, int headerRowNumber = 1); + ParsedTable UninformedParseTable(List columns, ExcelWorksheet workSheet, int headerRowNumber = 1, int maxScanHeaderRowThreashold = 100); + ParsedTable InformedParseTable(List columns, ExcelWorksheet workSheet, int headerRowNumber = 1); } } diff --git a/ExcelExtensions/Models/Column.cs b/ExcelExtensions/Models/Column.cs index 4b06602..1196280 100644 --- a/ExcelExtensions/Models/Column.cs +++ b/ExcelExtensions/Models/Column.cs @@ -1,7 +1,5 @@ // Copyright (c) Dominic Schira . All Rights Reserved. -using ExcelExtensions.Interfaces; -using System; using static ExcelExtensions.Enums.Enums; namespace ExcelExtensions.Models @@ -11,19 +9,11 @@ namespace ExcelExtensions.Models /// public class Column { - /// - /// Represents the location/letter of the excel column. Ex "C" - /// Used for exports and import where we know where to look and are not parsing for new col locations - /// - public string ExportColumnLetter { get; set; } - /// - /// Represents property name for the mapping object. - /// public string ModelProperty { get; set; } /// /// Represents the human readable column header name/title /// - public string TableHeaderTitle { get; set; } + public string DisplayName { get; set; } /// /// Represents the format type for the excel object /// @@ -37,32 +27,10 @@ public Column() { } - public Column(string modelPropertyName, string headerTitle, string columnLetter, FormatType format, int? decimalPrecision = null) - { - ExportColumnLetter = columnLetter; - ModelProperty = modelPropertyName; - TableHeaderTitle = headerTitle; - Format = format; - DecimalPrecision = decimalPrecision; - } - public Column(IExtensions _excelExtensions, Type modelType, string modelPropertyName, FormatType format, string columnLetter = null, int? decimalPrecision = null) - { - _excelExtensions.GetExportModelPropertyNameAndDisplayName(modelType, modelPropertyName, out string textTitle); - if (columnLetter != null) - { - ExportColumnLetter = columnLetter; - } - ModelProperty = modelPropertyName; - TableHeaderTitle = textTitle; - Format = format; - DecimalPrecision = decimalPrecision; - } - public Column(IExtensions _excelExtensions, Type modelType, string modelPropertyName, FormatType format, int columnLetterAsInt, int? decimalPrecision = null) + public Column(string modelPropertyName, string displayName, FormatType format, int? decimalPrecision = null) { - _excelExtensions.GetExportModelPropertyNameAndDisplayName(modelType, modelPropertyName, out string textTitle); - ExportColumnLetter = _excelExtensions.GetColumnLetter(columnLetterAsInt); ModelProperty = modelPropertyName; - TableHeaderTitle = textTitle; + DisplayName = displayName; Format = format; DecimalPrecision = decimalPrecision; } diff --git a/ExcelExtensions/Models/ColumnWithSeverity.cs b/ExcelExtensions/Models/ColumnWithSeverity.cs new file mode 100644 index 0000000..a2fdf28 --- /dev/null +++ b/ExcelExtensions/Models/ColumnWithSeverity.cs @@ -0,0 +1,29 @@ +// Copyright (c) Dominic Schira . All Rights Reserved. + +using static ExcelExtensions.Enums.Enums; + +namespace ExcelExtensions.Models +{ + public class ColumnWithSeverity : Column + { + /// + /// Represent severity if this column is not found while parsing + /// + public ParseExceptionSeverity MissingSeverity { get; set; } + + public ColumnWithSeverity() + { + + } + public ColumnWithSeverity(string modelPropertyName, string displayName, FormatType format, ParseExceptionSeverity missingSeverity = ParseExceptionSeverity.Error, int? decimalPrecision = null) : + base(modelPropertyName, displayName, format, decimalPrecision) + { + MissingSeverity = missingSeverity; + } + public ColumnWithSeverity(Column column, ParseExceptionSeverity missingSeverity = ParseExceptionSeverity.Error) : this(column.ModelProperty, column.DisplayName, column.Format, missingSeverity, column.DecimalPrecision) + { + } + + } + +} diff --git a/ExcelExtensions/Models/ExcelExtensionsColumnAttribute.cs b/ExcelExtensions/Models/ExcelExtensionsColumnAttribute.cs index a9ae891..b21295b 100644 --- a/ExcelExtensions/Models/ExcelExtensionsColumnAttribute.cs +++ b/ExcelExtensions/Models/ExcelExtensionsColumnAttribute.cs @@ -40,5 +40,7 @@ public class ExcelExtensionsColumnAttribute : Attribute public int? ImportColumnNumber { get; set; } + //TODO THROW ERRORS IF BOTH EXPORTS OR BOTH IMPORTS ARE DEFINED + } } diff --git a/ExcelExtensions/Models/ExportColumn.cs b/ExcelExtensions/Models/ExportColumn.cs new file mode 100644 index 0000000..d26c553 --- /dev/null +++ b/ExcelExtensions/Models/ExportColumn.cs @@ -0,0 +1,72 @@ +// Copyright (c) Dominic Schira . All Rights Reserved. + +using ExcelExtensions.Interfaces; +using System; +using static ExcelExtensions.Enums.Enums; + +namespace ExcelExtensions.Models +{ + /// + /// Represents an excel column + /// + public class ExportColumn : Column + { + /// + /// Represents the location/letter of the excel column. Ex "C" + /// Used for exports and import where we know where to look and are not parsing for new col locations + /// + [Obsolete] + public string ExportColumnLetter { get; set; } + public int ExportColumnNumber { get; set; } + /// + /// Represents property name for the mapping object. + /// + public string ModelProperty { get; set; } + /// + /// Represents the human readable column header name/title + /// + public string TableHeaderTitle { get; set; } + /// + /// Represents the format type for the excel object + /// + public FormatType Format { get; set; } + /// + /// Represents the number of decimal places in the output for export + /// + public int? DecimalPrecision { get; set; } + + public ExportColumn() + { + + } + public ExportColumn(string modelPropertyName, string headerTitle, int columnLetterAsInt, FormatType format, int? decimalPrecision = null) + { + ExportColumnNumber = columnLetterAsInt; + ModelProperty = modelPropertyName; + TableHeaderTitle = headerTitle; + Format = format; + DecimalPrecision = decimalPrecision; + } + public Column(IExtensions _excelExtensions, Type modelType, string modelPropertyName, FormatType format, string columnLetter = null, int? decimalPrecision = null) + { + _excelExtensions.GetExportModelPropertyNameAndDisplayName(modelType, modelPropertyName, out string textTitle); + if (columnLetter != null) + { + ExportColumnNumber = _excelExtensions.GetColumnNumber(columnLetter); + } + ModelProperty = modelPropertyName; + TableHeaderTitle = textTitle; + Format = format; + DecimalPrecision = decimalPrecision; + } + public Column(IExtensions _excelExtensions, Type modelType, string modelPropertyName, FormatType format, int columnLetterAsInt, int? decimalPrecision = null) + { + _excelExtensions.GetExportModelPropertyNameAndDisplayName(modelType, modelPropertyName, out string textTitle); + ExportColumnNumber = columnLetterAsInt; + ModelProperty = modelPropertyName; + TableHeaderTitle = textTitle; + Format = format; + DecimalPrecision = decimalPrecision; + } + } +} diff --git a/ExcelExtensions/Models/ImportColumnTemplate.cs b/ExcelExtensions/Models/ImportColumnTemplate.cs deleted file mode 100644 index 9b25667..0000000 --- a/ExcelExtensions/Models/ImportColumnTemplate.cs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) Dominic Schira . All Rights Reserved. - -using ExcelExtensions.Interfaces; -using System.Collections.Generic; -using System.Linq; - -namespace ExcelExtensions.Models -{ - //TODO: replace with data attributes - public class ImportColumn - { - /// - /// Represent the list of options for the header name - /// - public List ColumnHeaderOptions { get; set; } - /// - /// If required then if not then warning - /// - public bool IsRequired { get; set; } - public Column Column { get; set; } - public ImportColumn() - { - - } - /// - /// Adds the header name/title from the column - /// - /// - /// - /// Optional names to search for - public ImportColumn(Column column, bool required, List columnOptions = null) - { - ColumnHeaderOptions = columnOptions ?? new List(); - ColumnHeaderOptions.Add(column.TableHeaderTitle); - IsRequired = required; - Column = column; - } - } - - /// - /// This class has our number populated so that if we have a letter provided we get to have a number - /// - public class ImportColumnWithCellAddress : ImportColumn - { - /// - /// used as a pointer for where we are importing and saved if we are looking for a column that doesn't have a letter - /// This will override the letter and use the number for data - /// - public int ImportColumnNumber { get; set; } - - public ImportColumnWithCellAddress() : base() - { - - } - - public ImportColumnWithCellAddress(IExtensions excelExtensions, ImportColumn template) : base(template.Column, template.IsRequired, template.ColumnHeaderOptions) - { - ImportColumnNumber = template.Column.ExportColumnLetter == null ? 0 : excelExtensions.GetColumnNumber(template.Column.ExportColumnLetter); - } - } - - -} diff --git a/ExcelExtensions/Models/LazyColumn.cs b/ExcelExtensions/Models/LazyColumn.cs new file mode 100644 index 0000000..4046e2c --- /dev/null +++ b/ExcelExtensions/Models/LazyColumn.cs @@ -0,0 +1,20 @@ +// Copyright (c) Dominic Schira . All Rights Reserved. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ExcelExtensions.Models +{ + public class LazyColumn : Column + { + public int ColumnLocation { get; set; } + + public LazyColumn() + { + + } + } +} diff --git a/ExcelExtensions/Models/ParseException.cs b/ExcelExtensions/Models/ParseException.cs index 4662925..d03dda6 100644 --- a/ExcelExtensions/Models/ParseException.cs +++ b/ExcelExtensions/Models/ParseException.cs @@ -72,7 +72,7 @@ public ParseException(string sheetName, Column column) : this (sheetName) //ColumnHeader = column.ColumnHeader; //todo FormatType = column.Format; } - public ParseException(string sheetName, ImportColumn column) : this (sheetName, column.Column) + public ParseException(string sheetName, UninformedImportColumn column) : this (sheetName, column.Column) { Severity = (column.IsRequired) ? ParseExceptionSeverity.Error : ParseExceptionSeverity.Warning; } diff --git a/ExcelExtensions/Models/UninformedImportColumn.cs b/ExcelExtensions/Models/UninformedImportColumn.cs new file mode 100644 index 0000000..88f66db --- /dev/null +++ b/ExcelExtensions/Models/UninformedImportColumn.cs @@ -0,0 +1,80 @@ +// Copyright (c) Dominic Schira . All Rights Reserved. + +using ExcelExtensions.Interfaces; +using System; +using System.Collections.Generic; +using System.Linq; +using static ExcelExtensions.Enums.Enums; + +namespace ExcelExtensions.Models +{ + public class ImportColumn : ColumnWithSeverity + { + public bool IsRequired { get; set; } + + public ImportColumn() : base() + { + IsRequired = MissingSeverity == ParseExceptionSeverity.Error; + } + + public ImportColumn(Column column, bool required) : base(column, required ? ParseExceptionSeverity.Error : ParseExceptionSeverity.Warning) + { + + } + public ImportColumn(string modelPropertyName, string displayName, FormatType format, bool required = true, int? decimalPrecision = null) : + base(modelPropertyName, displayName, format, required ? ParseExceptionSeverity.Error : ParseExceptionSeverity.Warning, decimalPrecision) + { + + } + } + /// + /// SCAN AND PARSE + /// + public class UninformedImportColumn : ImportColumn + { + /// + /// Represent the list of options for the header name + /// Used for parseing + /// + public List DisplayNameOptions { get; set; } + public UninformedImportColumn() + { + + } + + + /// + /// Adds the header name/title from the column + /// + /// + /// + /// Optional names to search for + public UninformedImportColumn(Column column, bool required, List columnOptions = null) : base(column, required) + { + DisplayNameOptions = columnOptions ?? new List(); + DisplayNameOptions.Add(column.DisplayName); + MissingSeverity = required ? ParseExceptionSeverity.Error : ParseExceptionSeverity.Warning; + } + } + + /// + /// JUST PARSE + /// + public class InformedImportColumn : ImportColumn + { + /// + /// used as a pointer for where we are importing and saved if we are looking for a column that doesn't have a letter + /// This will override the letter and use the number for data + /// + public int ImportColumnNumber { get; set; } + + public InformedImportColumn() : base() + { + + } + + + } + + +} diff --git a/ExcelExtensions/Providers/Export/Exporter.cs b/ExcelExtensions/Providers/Export/Exporter.cs index 4e27bce..9d1c560 100644 --- a/ExcelExtensions/Providers/Export/Exporter.cs +++ b/ExcelExtensions/Providers/Export/Exporter.cs @@ -49,7 +49,7 @@ public void ExportColumns(ref ExcelWorksheet sheet, List rows, List public void FormatColumn(Column column, ref ExcelWorksheet sheet) { - FormatColumn(ref sheet, column.ExportColumnLetter, column.Format, column.DecimalPrecision); + FormatColumn(ref sheet, column.ExportColumnNumber, column.Format, column.DecimalPrecision); } + + public void FormatColumn(ref ExcelWorksheet sheet, string columnLetter, FormatType formatter, int? decimalPrecision = null) + { + FormatColumn(ref sheet, _excelProvider.GetColumnNumber(columnLetter), formatter, decimalPrecision); + } + /// - public void FormatColumn(ref ExcelWorksheet sheet, string column, FormatType formatter, int? decimalPrecision = null) + public void FormatColumn(ref ExcelWorksheet sheet, int columnNumber, FormatType formatter, int? decimalPrecision = null) { //Styling if (formatter == FormatType.String) { - sheet.Column(_excelProvider.GetColumnNumber(column)).Width = 21; + sheet.Column(columnNumber).Width = 21; } else if (formatter == FormatType.Currency) { @@ -109,27 +115,27 @@ public void FormatColumn(ref ExcelWorksheet sheet, string column, FormatType for { string formatString = "$#,##0"; formatString = _excelProvider.AddDecimalPlacesToFormat(decimalPrecision, formatString); - sheet.Column(_excelProvider.GetColumnNumber(column)).Style.Numberformat.Format = formatString; + sheet.Column(columnNumber).Style.Numberformat.Format = formatString; } else { - sheet.Column(_excelProvider.GetColumnNumber(column)).Style.Numberformat.Format = "$#,##0.00"; + sheet.Column(columnNumber).Style.Numberformat.Format = "$#,##0.00"; } - sheet.Column(_excelProvider.GetColumnNumber(column)).Width = 17; + sheet.Column(columnNumber).Width = 17; } else if (formatter == FormatType.Date) { if (DateTimeFormatInfo.CurrentInfo != null) { - sheet.Column(_excelProvider.GetColumnNumber(column)).Style.Numberformat.Format = DateTimeFormatInfo.CurrentInfo.ShortDatePattern; + sheet.Column(columnNumber).Style.Numberformat.Format = DateTimeFormatInfo.CurrentInfo.ShortDatePattern; } - sheet.Column(_excelProvider.GetColumnNumber(column)).Width = 15; + sheet.Column(columnNumber).Width = 15; } else if (formatter == FormatType.Duration) { - sheet.Column(_excelProvider.GetColumnNumber(column)).Style.Numberformat.Format = "[h]:mm:ss"; - sheet.Column(_excelProvider.GetColumnNumber(column)).Width = 15; + sheet.Column(columnNumber).Style.Numberformat.Format = "[h]:mm:ss"; + sheet.Column(columnNumber).Width = 15; } else if (formatter == FormatType.Decimal) { @@ -137,18 +143,18 @@ public void FormatColumn(ref ExcelWorksheet sheet, string column, FormatType for { string formatString = "#,##0"; formatString = _excelProvider.AddDecimalPlacesToFormat(decimalPrecision, formatString); - sheet.Column(_excelProvider.GetColumnNumber(column)).Style.Numberformat.Format = formatString; + sheet.Column(columnNumber).Style.Numberformat.Format = formatString; } else { - sheet.Column(_excelProvider.GetColumnNumber(column)).Style.Numberformat.Format = "#,##0.0000"; + sheet.Column(columnNumber).Style.Numberformat.Format = "#,##0.0000"; } - sheet.Column(_excelProvider.GetColumnNumber(column)).Width = 15; + sheet.Column(columnNumber).Width = 15; } else if (formatter == FormatType.Int) { - sheet.Column(_excelProvider.GetColumnNumber(column)).Style.Numberformat.Format = "0"; - sheet.Column(_excelProvider.GetColumnNumber(column)).Width = 13; + sheet.Column(columnNumber).Style.Numberformat.Format = "0"; + sheet.Column(columnNumber).Width = 13; } else if (formatter == FormatType.Percent) { @@ -156,24 +162,35 @@ public void FormatColumn(ref ExcelWorksheet sheet, string column, FormatType for { string formatString = "0"; formatString = _excelProvider.AddDecimalPlacesToFormat(decimalPrecision, formatString); - sheet.Column(_excelProvider.GetColumnNumber(column)).Style.Numberformat.Format = formatString += "%"; + sheet.Column(columnNumber).Style.Numberformat.Format = formatString += "%"; } else { - sheet.Column(_excelProvider.GetColumnNumber(column)).Style.Numberformat.Format = "0%"; + sheet.Column(columnNumber).Style.Numberformat.Format = "0%"; } - sheet.Column(_excelProvider.GetColumnNumber(column)).Width = 13; + sheet.Column(columnNumber).Width = 13; } } /// public void FormatColumnRange(ExcelWorksheet itemcodeSheet, string startColumn, string endColumn, FormatType format, int? decimalPrecision = null) { - if (_excelProvider.GetColumnNumber(startColumn) > _excelProvider.GetColumnNumber(endColumn)) + int start = _excelProvider.GetColumnNumber(startColumn); + int end = _excelProvider.GetColumnNumber(endColumn); + if (start > end) + { + throw new ArgumentOutOfRangeException(nameof(startColumn), $"{nameof(startColumn)} must be less than {nameof(endColumn)}"); + } + FormatColumnRange(itemcodeSheet, start, end, format, decimalPrecision); + } + public void FormatColumnRange(ExcelWorksheet itemcodeSheet, int startColumn, int endColumn, FormatType format, int? decimalPrecision = null) + { + + if (startColumn > endColumn) { throw new ArgumentOutOfRangeException(nameof(startColumn), $"{nameof(startColumn)} must be less than {nameof(endColumn)}"); } - string currenctColumn = startColumn; + int currenctColumn = startColumn; do { FormatColumn(ref itemcodeSheet, currenctColumn, format, decimalPrecision); @@ -183,7 +200,7 @@ public void FormatColumnRange(ExcelWorksheet itemcodeSheet, string startColumn, { break; } - currenctColumn = _excelProvider.GetColumnLetter(_excelProvider.GetColumnNumber(currenctColumn) + 1); + currenctColumn++; } while (currenctColumn != endColumn); } diff --git a/ExcelExtensions/Providers/Extensions.cs b/ExcelExtensions/Providers/Extensions.cs index 59afdeb..872bd34 100644 --- a/ExcelExtensions/Providers/Extensions.cs +++ b/ExcelExtensions/Providers/Extensions.cs @@ -18,20 +18,20 @@ namespace ExcelExtensions.Providers public class Extensions : IExtensions { #region developer exceptions - public KeyValuePair LogDeveloperException(string worksheetName, ImportColumn importColumn, string cellAddress, string message, string modelPropertyName) + public KeyValuePair LogDeveloperException(string worksheetName, UninformedImportColumn importColumn, string cellAddress, string message, string modelPropertyName) { ParseException parseException = LogDeveloperExceptionParseException(worksheetName, importColumn, cellAddress, message); return new KeyValuePair(modelPropertyName, parseException); } - public KeyValuePair LogDeveloperException(string worksheetName, ImportColumn importColumn, string cellAddress, int rowNumber, string message) + public KeyValuePair LogDeveloperException(string worksheetName, UninformedImportColumn importColumn, string cellAddress, int rowNumber, string message) { ParseException parseException = LogDeveloperExceptionParseException(worksheetName, importColumn, cellAddress, message); return new KeyValuePair(rowNumber, parseException); } - private ParseException LogDeveloperExceptionParseException(string worksheetName, ImportColumn importColumn, string cellAddress, string exeptionMessage) + private ParseException LogDeveloperExceptionParseException(string worksheetName, UninformedImportColumn importColumn, string cellAddress, string exeptionMessage) { //ParseException parseException = new(worksheetName, displayName, cellAddress, null, "An error occurred when trying to set the property info. The error is: " + message) ParseException parseException = new(worksheetName, importColumn.Column) @@ -45,21 +45,21 @@ private ParseException LogDeveloperExceptionParseException(string worksheetName, return parseException; } - public KeyValuePair LogNullReferenceException(string worksheetName, ImportColumn displayName, string cellAddress, string modelPropertyName) + public KeyValuePair LogNullReferenceException(string worksheetName, UninformedImportColumn displayName, string cellAddress, string modelPropertyName) { ParseException parseException = LogNullReferenceExceptionParseException(worksheetName, displayName, cellAddress); return new KeyValuePair(modelPropertyName, parseException); } - public KeyValuePair LogNullReferenceException(string worksheetName, ImportColumn displayName, string cellAddress, int rowNumber) + public KeyValuePair LogNullReferenceException(string worksheetName, UninformedImportColumn displayName, string cellAddress, int rowNumber) { ParseException parseException = LogNullReferenceExceptionParseException(worksheetName, displayName, cellAddress); return new KeyValuePair(rowNumber, parseException); } - private ParseException LogNullReferenceExceptionParseException(string worksheetName, ImportColumn column, string cellAddress) + private ParseException LogNullReferenceExceptionParseException(string worksheetName, UninformedImportColumn column, string cellAddress) { ParseException parseException = new(worksheetName, column) { @@ -71,21 +71,21 @@ private ParseException LogNullReferenceExceptionParseException(string worksheetN return parseException; } - public KeyValuePair LogCellException(string worksheetName, ImportColumn displayName, string cellAddress, string modelPropertyName) + public KeyValuePair LogCellException(string worksheetName, UninformedImportColumn displayName, string cellAddress, string modelPropertyName) { ParseException parseException = LogCellExceptionParseException(worksheetName, displayName, cellAddress); return new KeyValuePair(modelPropertyName, parseException); } - public KeyValuePair LogCellException(string worksheetName, ImportColumn displayName, string cellAddress, int rowNumber) + public KeyValuePair LogCellException(string worksheetName, UninformedImportColumn displayName, string cellAddress, int rowNumber) { ParseException parseException = LogCellExceptionParseException(worksheetName, displayName, cellAddress); return new KeyValuePair(rowNumber, parseException); } - private ParseException LogCellExceptionParseException(string worksheetName, ImportColumn column, string cellAddress) + private ParseException LogCellExceptionParseException(string worksheetName, UninformedImportColumn column, string cellAddress) { ParseException parseException = new(worksheetName, column) { diff --git a/ExcelExtensions/Providers/Import/ImportMapFactory.cs b/ExcelExtensions/Providers/Import/ImportMapFactory.cs index 400f7f5..f6e95c2 100644 --- a/ExcelExtensions/Providers/Import/ImportMapFactory.cs +++ b/ExcelExtensions/Providers/Import/ImportMapFactory.cs @@ -23,7 +23,7 @@ public ImportMapFactory(IExtensions excelExtensions) } - public List MapObjectToImportColumns(Type modelType, FormatType formatType = FormatType.String, int startColumnNumber = 1) + public List MapObjectToImportColumns(Type modelType, FormatType formatType = FormatType.String, int startColumnNumber = 1) { //If you give me an int you know where it is, or if you give me a letter you know where it is @@ -40,7 +40,7 @@ public List MapObjectToImportColumns(Type modelType, FormatType fo //Could possible make Column and protected class and make ImportColumn and ExportColum then a class that encapsulates both for a LazyColumn int currentColumnNumber = startColumnNumber; - List excelColumnDefinitionArray = new(); + List excelColumnDefinitionArray = new(); foreach (PropertyInfo item in modelType.GetProperties()) { @@ -57,7 +57,7 @@ public List MapObjectToImportColumns(Type modelType, FormatType fo bool required = attribute?.IsRequired ?? true; // List importKeys = attribute?.ImportColumnTitleOptions ?? new List() { modelPropertyName, textTitle }; - excelColumnDefinitionArray.Add(new ImportColumnWithCellAddress() + excelColumnDefinitionArray.Add(new InformedImportColumn() { //If already know our column letter lets use that. ImportColumnNumber = attribute?.ExportColumnLetter == null ? 0 : _excelExtensions.GetColumnNumber(attribute.ExportColumnLetter), @@ -66,7 +66,7 @@ public List MapObjectToImportColumns(Type modelType, FormatType fo letter, format, attribute?.DecimalPrecision), - ColumnHeaderOptions = importKeys, + DisplayNameOptions = importKeys, IsRequired = required }); //next column diff --git a/ExcelExtensions/Providers/Import/Parse/TableParser.cs b/ExcelExtensions/Providers/Import/Parse/TableParser.cs index fd850ba..a9ce54d 100644 --- a/ExcelExtensions/Providers/Import/Parse/TableParser.cs +++ b/ExcelExtensions/Providers/Import/Parse/TableParser.cs @@ -33,7 +33,7 @@ public TableParser(IExtensions excelExtensions, IParser parser) _parseResults = new ParsedTable(); _requiredFieldMissingMessages = new List(); } - public ParsedTable ScanForColumnsAndParseTable(List columns, ExcelWorksheet workSheet, int headerRowNumber = 1, int maxScanHeaderRowThreashold = 100) + public ParsedTable UninformedParseTable(List columns, ExcelWorksheet workSheet, int headerRowNumber = 1, int maxScanHeaderRowThreashold = 100) { if (_excelExtensions is null) { @@ -41,7 +41,7 @@ public ParsedTable ScanForColumnsAndParseTable(List columns, Ex } int rowScanCount = 0; - List columnsWithCellAddresses = CheckForMissingColumnNumbersInImportColumnTemplates(columns); + List columnsWithCellAddresses = CheckForMissingColumnNumbersInImportColumnTemplates(columns); //Check for each of the expected columns in ScanForHeaderRow(columnsWithCellAddresses, ref workSheet, ref headerRowNumber, maxScanHeaderRowThreashold, ref rowScanCount); @@ -55,27 +55,37 @@ public ParsedTable ScanForColumnsAndParseTable(List columns, Ex return ParseRows(columnsWithCellAddresses, workSheet, headerRowNumber); } - public ParsedTable ParseTable(List columns, ExcelWorksheet workSheet, int headerRowNumber = 1) + public ParsedTable InformedParseTable(List columns, ExcelWorksheet workSheet, int headerRowNumber = 1) { if (_excelExtensions is null) { throw new ArgumentNullException(nameof(IExtensions), $"Make sure when TableParser is constructed that {nameof(IExtensions)} gets passed in."); } - List columnsWithCellAddresses = CheckForMissingColumnNumbersInImportColumnTemplates(columns); + List columnsWithCellAddresses = CheckForMissingColumnNumbersInImportColumnTemplates(columns); - if (columnsWithCellAddresses.Any(x => x.IsRequired && x.ImportColumnNumber <= 0)) + return InformedParseTable(columnsWithCellAddresses, workSheet, headerRowNumber); + } + public ParsedTable InformedParseTable(List columns, ExcelWorksheet workSheet, int headerRowNumber = 1) + { + if (_excelExtensions is null) + { + throw new ArgumentNullException(nameof(IExtensions), $"Make sure when TableParser is constructed that {nameof(IExtensions)} gets passed in."); + } + + if (columns.Any(x => x.IsRequired && x.ImportColumnNumber <= 0)) { throw new ArgumentOutOfRangeException(nameof(columns), "All ColumnTemplate's must have a ColumnNumber. If the ColumnNumber is unknown use the ScanForColumnsAndParseTable method."); } //Assign required columns - foreach (ImportColumnWithCellAddress col in columnsWithCellAddresses.Where(x => x.IsRequired)) + foreach (InformedImportColumn col in columns.Where(x => x.IsRequired)) { - _requiredFieldsColumnLocations.Add(col.Column.ExportColumnLetter); + //TODO this might need changed... + _requiredFieldsColumnLocations.Add(_excelExtensions.GetColumnLetter(col.ImportColumnNumber)); } //Parse each row - return ParseRows(columnsWithCellAddresses, workSheet, headerRowNumber); + return ParseRows(columns, workSheet, headerRowNumber); } /// @@ -85,7 +95,7 @@ public ParsedTable ParseTable(List columns, ExcelWorksheet work /// /// /// - private ParsedTable ParseRows(List columnsWithCellAddresses, ExcelWorksheet workSheet, int headerRowId) + private ParsedTable ParseRows(List columnsWithCellAddresses, ExcelWorksheet workSheet, int headerRowId) { for (int rowNumber = headerRowId + 1; rowNumber <= workSheet.Dimension.End.Row; rowNumber++) { @@ -93,7 +103,7 @@ private ParsedTable ParseRows(List columnsWithCe _singleRowErrors.Clear(); _model = Activator.CreateInstance(); - foreach (ImportColumnWithCellAddress coltemplate in columnsWithCellAddresses) + foreach (InformedImportColumn coltemplate in columnsWithCellAddresses) { //If its at defualt(0) or we have reached the end of the sheet bail out if (coltemplate.ImportColumnNumber < 1 || coltemplate.ImportColumnNumber > workSheet.Dimension.End.Column) @@ -143,12 +153,12 @@ private ParsedTable ParseRows(List columnsWithCe /// Get the cell address using the extension from the data the user provided in the import map /// /// - private List CheckForMissingColumnNumbersInImportColumnTemplates(List columns) + private List CheckForMissingColumnNumbersInImportColumnTemplates(List columns) { - List columnsWithCellAddresses = new(); - foreach (ImportColumn item in columns) + List columnsWithCellAddresses = new(); + foreach (UninformedImportColumn item in columns) { - columnsWithCellAddresses.Add(new ImportColumnWithCellAddress(_excelExtensions, item)); + columnsWithCellAddresses.Add(new InformedImportColumn(_excelExtensions, item)); } return columnsWithCellAddresses; } @@ -163,7 +173,7 @@ private List CheckForMissingColumnNumbersInImportCo /// /// /// There must be at least one required field. - private void ScanForHeaderRow(List columns, ref ExcelWorksheet workSheet, ref int headerRowNumber, int maxScanHeaderRowThreashold, ref int rowScanCount) + private void ScanForHeaderRow(List columns, ref ExcelWorksheet workSheet, ref int headerRowNumber, int maxScanHeaderRowThreashold, ref int rowScanCount) { do { @@ -205,7 +215,7 @@ private void ScanForHeaderRow(List columns, ref Exc /// /// /// - private bool CheckMissingScannedColumns(int headerRowId, int maxScanHeaderRowThreashold, int rowScanCount, List columns) + private bool CheckMissingScannedColumns(int headerRowId, int maxScanHeaderRowThreashold, int rowScanCount, List columns) { if (rowScanCount >= maxScanHeaderRowThreashold && _requiredFieldMissingMessages.Count == columns.Where(x => x.IsRequired).Count()) @@ -251,13 +261,13 @@ private bool CheckMissingScannedColumns(int headerRowId, int maxScanHeaderRowThr /// /// /// - private void FindColumnNamesAndCheckRequiredColumns(List columns, ref ExcelWorksheet workSheet, ref int headerRowId) + private void FindColumnNamesAndCheckRequiredColumns(List columns, ref ExcelWorksheet workSheet, ref int headerRowId) { - foreach (ImportColumnWithCellAddress coltemplate in columns) + foreach (InformedImportColumn coltemplate in columns) { foreach (ExcelRangeBase firstRowCell in workSheet.Cells[headerRowId, workSheet.Dimension.Start.Column, headerRowId, workSheet.Dimension.End.Column]) { - if (coltemplate.ColumnHeaderOptions.Any(x => x.Equals(firstRowCell.Text, StringComparison.OrdinalIgnoreCase))) + if (coltemplate.DisplayNameOptions.Any(x => x.Equals(firstRowCell.Text, StringComparison.OrdinalIgnoreCase))) { coltemplate.ImportColumnNumber = firstRowCell.Start.Column; continue; @@ -303,7 +313,7 @@ private void FindColumnNamesAndCheckRequiredColumns(List /// /// Will throw errors. disable them when debugging through this dll file. - private void ParseCell(ExcelWorksheet workSheet, int rowNumber, ImportColumn coltemplate, ExcelRange cell) + private void ParseCell(ExcelWorksheet workSheet, int rowNumber, UninformedImportColumn coltemplate, ExcelRange cell) { switch (coltemplate.Column.Format) { @@ -460,7 +470,7 @@ private void ParseCell(ExcelWorksheet workSheet, int rowNumber, ImportColumn col decimalList = (Dictionary)list; } - decimalList.Add(coltemplate.ColumnHeaderOptions[0], val); + decimalList.Add(coltemplate.DisplayNameOptions[0], val); modelPropertyInfo.SetValue(_model, decimalList, null); } @@ -519,7 +529,7 @@ private void ParseCell(ExcelWorksheet workSheet, int rowNumber, ImportColumn col stringlist = (Dictionary)list; } - stringlist.Add(coltemplate.ColumnHeaderOptions[0], cellVal); + stringlist.Add(coltemplate.DisplayNameOptions[0], cellVal); modelPropertyInfo.SetValue(_model, stringlist, null); } @@ -563,7 +573,7 @@ private void ParseCell(ExcelWorksheet workSheet, int rowNumber, ImportColumn col /// /// /// - private void SetValue(ExcelWorksheet workSheet, int rowNumber, ImportColumn coltemplate, ExcelRange cell, object value) + private void SetValue(ExcelWorksheet workSheet, int rowNumber, UninformedImportColumn coltemplate, ExcelRange cell, object value) { try { diff --git a/ExcelExtensionsTests/Providers/ParseTableTest.cs b/ExcelExtensionsTests/Providers/ParseTableTest.cs index ee8698e..097eefb 100644 --- a/ExcelExtensionsTests/Providers/ParseTableTest.cs +++ b/ExcelExtensionsTests/Providers/ParseTableTest.cs @@ -67,15 +67,15 @@ private void CreateTestFile(ref ExcelWorksheet sheet, List GetScannedColumns() + private List GetScannedColumns() { Type type = typeof(ParseTableTestBaseModel); - return new List() + return new List() { - new ImportColumn(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.RequiredText), FormatType.String), true), - new ImportColumn(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.Date), FormatType.Date), true), - new ImportColumn(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.Decimal), FormatType.Decimal), true), - new ImportColumn(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.OptionalText), FormatType.String), false), + new UninformedImportColumn(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.RequiredText), FormatType.String), true), + new UninformedImportColumn(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.Date), FormatType.Date), true), + new UninformedImportColumn(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.Decimal), FormatType.Decimal), true), + new UninformedImportColumn(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.OptionalText), FormatType.String), false), }; } /// @@ -83,17 +83,17 @@ private List GetScannedColumns() /// /// /// - private List GetKnownColumns(int colStart) + private List GetKnownColumns(int colStart) { int i = colStart; Type type = typeof(ParseTableTestBaseModel); - return new List() + return new List() { - new ImportColumn(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.RequiredText), FormatType.String, i++), true), - new ImportColumn(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.Date), FormatType.Date, i++), true), - new ImportColumn(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.Decimal), FormatType.Decimal, i++), true), - new ImportColumn(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.OptionalText), FormatType.String, i++), false), + new UninformedImportColumn(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.RequiredText), FormatType.String, i++), true), + new UninformedImportColumn(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.Date), FormatType.Date, i++), true), + new UninformedImportColumn(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.Decimal), FormatType.Decimal, i++), true), + new UninformedImportColumn(new Column(_excelExtensionsProvider, type, nameof(ParseTableTestBaseModel.OptionalText), FormatType.String, i++), false), }; } @@ -156,7 +156,7 @@ public void ParseTable_BasicTest_Pass() CreateTestFile(ref worksheet, rowsOfTestData); //Act - var result = _tableParser.ParseTable(GetKnownColumns(1), worksheet).Rows; + var result = _tableParser.InformedParseTable(GetKnownColumns(1), worksheet).Rows; //Assert Assert.Equal(rowsOfTestData.First(), result.First().Value); @@ -174,7 +174,7 @@ public void ParseTable_BasicTest_NoNumbers_Fail() CreateTestFile(ref worksheet, rowsOfTestData); //Act - var ex = Assert.Throws(() => _tableParser.ParseTable(GetScannedColumns(), worksheet).Rows); + var ex = Assert.Throws(() => _tableParser.InformedParseTable(GetScannedColumns(), worksheet).Rows); //Assert Assert.Equal("All ColumnTemplate's must have a ColumnNumber. If the ColumnNumber is unknown use the ScanForColumnsAndParseTable method. (Parameter 'columns')", ex.Message); @@ -196,7 +196,7 @@ public void SearchAndParseTable_BasicTest_Pass() CreateTestFile(ref worksheet, rowsOfTestData); //Act - var result = _tableParser.ScanForColumnsAndParseTable(GetScannedColumns(), worksheet).Rows; + var result = _tableParser.UninformedParseTable(GetScannedColumns(), worksheet).Rows; //Assert Assert.Equal(rowsOfTestData.First(), result.First().Value); @@ -218,7 +218,7 @@ public void SearchAndParseTable_ShiftedLocations_WithHeaderRowInput_Pass(int row CreateTestFile(ref worksheet, rowsOfTestData, row, col); //Act - var result = _tableParser.ScanForColumnsAndParseTable(GetScannedColumns(), worksheet, row).Rows; + var result = _tableParser.UninformedParseTable(GetScannedColumns(), worksheet, row).Rows; //Assert Assert.Equal(rowsOfTestData.First(), result.First().Value); @@ -252,7 +252,7 @@ public void SearchAndParseTable_ShiftedLocations_WithoutHeaderRowInput_Pass(int CreateTestFile(ref worksheet, rowsOfTestData, row, col); //Act - var result = _tableParser.ScanForColumnsAndParseTable(GetScannedColumns(), worksheet).Rows; + var result = _tableParser.UninformedParseTable(GetScannedColumns(), worksheet).Rows; //Assert Assert.Equal(rowsOfTestData.First(), result.First().Value); @@ -271,7 +271,7 @@ public void SearchAndParseTable_WithHeaderRowInput_LastRowOfSearch_Pass() CreateTestFile(ref worksheet, rowsOfTestData, 104, 1); //Act - var result = _tableParser.ScanForColumnsAndParseTable(GetScannedColumns(), worksheet, 5).Rows; + var result = _tableParser.UninformedParseTable(GetScannedColumns(), worksheet, 5).Rows; //Assert Assert.Equal(rowsOfTestData.First(), result.First().Value); @@ -315,7 +315,7 @@ public void SearchAndParseTable_MissingOptionalColumn_Pass() } //Act - var result = _tableParser.ScanForColumnsAndParseTable(GetScannedColumns(), worksheet); + var result = _tableParser.UninformedParseTable(GetScannedColumns(), worksheet); //Assert Assert.Equal(rowsOfTestData.First(), result.Rows.First().Value); @@ -339,7 +339,7 @@ public void SearchAndParseTable_HeaderGreaterThanMaxSearch_Error() CreateTestFile(ref worksheet, rowsOfTestData, 101, 1); //Act - var result = _tableParser.ScanForColumnsAndParseTable(GetScannedColumns(), worksheet).Exceptions; + var result = _tableParser.UninformedParseTable(GetScannedColumns(), worksheet).Exceptions; string errorMsg = "Could not find columns. Please check spelling of header columns and make sure all required columns are in the worksheet."; //Assert Assert.Equal(errorMsg, result.First().Value.Message); @@ -380,7 +380,7 @@ public void SearchAndParseTable_MissingRequiredColumn_Error() } //Act - ParseException result = _tableParser.ScanForColumnsAndParseTable(GetScannedColumns(), worksheet).Exceptions.First().Value; + ParseException result = _tableParser.UninformedParseTable(GetScannedColumns(), worksheet).Exceptions.First().Value; //Assert Assert.Equal(errorMessage.Severity, result.Severity); @@ -410,7 +410,7 @@ public void ParseRow_WithNullRequiredInMiddleOfData() CreateTestFile(ref worksheet, rowsOfTestData, 1, 1); //Act - var result = _tableParser.ScanForColumnsAndParseTable(GetScannedColumns(), worksheet); + var result = _tableParser.UninformedParseTable(GetScannedColumns(), worksheet); //Assert Assert.Equal(rowsOfTestData.First(x => x.RequiredText == "First Valid Data"), result.Rows[2]); diff --git a/WebApplication/Providers/SampleProvider.cs b/WebApplication/Providers/SampleProvider.cs index e8a497e..aa854bb 100644 --- a/WebApplication/Providers/SampleProvider.cs +++ b/WebApplication/Providers/SampleProvider.cs @@ -57,7 +57,7 @@ public Dictionary ScanForColumnsAndParseTable(IFormFile f throw new ImportException(exception); } - ParsedTable parsedTable = _tableParser.ScanForColumnsAndParseTable(GetTableColumnTemplates(), sheet); + ParsedTable parsedTable = _tableParser.UninformedParseTable(GetTableColumnTemplates(), sheet); if (parsedTable.Exceptions.Any(x => x.Value.Severity == ParseExceptionSeverity.Error)) { @@ -79,32 +79,32 @@ public Dictionary ScanForColumnsAndParseTable(IFormFile f /// Sets the requiredments for import and our model property. /// /// - private List GetTableColumnTemplates() + private List GetTableColumnTemplates() { //TODO USE REFLECTION https://github.com/domshyra/ExcelExtensions/issues/15 List cols = SampleTableColumns(); - return new List() + return new List() { // Col Req? - new ImportColumn(GetColumn(cols, nameof(SampleTableModel.Text)), true), - new ImportColumn(GetColumn(cols, nameof(SampleTableModel.Date)), true), - new ImportColumn(GetColumn(cols, nameof(SampleTableModel.DateAsText)), true), - new ImportColumn(GetColumn(cols, nameof(SampleTableModel.DateAsGeneral)), false), - new ImportColumn(GetColumn(cols, nameof(SampleTableModel.Duration)), false), - new ImportColumn(GetColumn(cols, nameof(SampleTableModel.Percent)), true), - new ImportColumn(GetColumn(cols, nameof(SampleTableModel.PercentAsText)), false), - new ImportColumn(GetColumn(cols, nameof(SampleTableModel.PercentAsNumber)), false), - new ImportColumn(GetColumn(cols, nameof(SampleTableModel.BoolAsYESNO)), false), - new ImportColumn(GetColumn(cols, nameof(SampleTableModel.BoolAsTrueFalse)), false), - new ImportColumn(GetColumn(cols, nameof(SampleTableModel.BoolAs10)), false), - new ImportColumn(GetColumn(cols, nameof(SampleTableModel.Currency)), false), - new ImportColumn(GetColumn(cols, nameof(SampleTableModel.CurrencyAsText)), false), - new ImportColumn(GetColumn(cols, nameof(SampleTableModel.CurrencyAsGeneral)), false), - new ImportColumn(GetColumn(cols, nameof(SampleTableModel.Decimal)), false), - new ImportColumn(GetColumn(cols, nameof(SampleTableModel.DecimalAsText)), false), - new ImportColumn(GetColumn(cols, nameof(SampleTableModel.RequiredText)), true), - new ImportColumn(GetColumn(cols, nameof(SampleTableModel.OptionalText)), false), + new UninformedImportColumn(GetColumn(cols, nameof(SampleTableModel.Text)), true), + new UninformedImportColumn(GetColumn(cols, nameof(SampleTableModel.Date)), true), + new UninformedImportColumn(GetColumn(cols, nameof(SampleTableModel.DateAsText)), true), + new UninformedImportColumn(GetColumn(cols, nameof(SampleTableModel.DateAsGeneral)), false), + new UninformedImportColumn(GetColumn(cols, nameof(SampleTableModel.Duration)), false), + new UninformedImportColumn(GetColumn(cols, nameof(SampleTableModel.Percent)), true), + new UninformedImportColumn(GetColumn(cols, nameof(SampleTableModel.PercentAsText)), false), + new UninformedImportColumn(GetColumn(cols, nameof(SampleTableModel.PercentAsNumber)), false), + new UninformedImportColumn(GetColumn(cols, nameof(SampleTableModel.BoolAsYESNO)), false), + new UninformedImportColumn(GetColumn(cols, nameof(SampleTableModel.BoolAsTrueFalse)), false), + new UninformedImportColumn(GetColumn(cols, nameof(SampleTableModel.BoolAs10)), false), + new UninformedImportColumn(GetColumn(cols, nameof(SampleTableModel.Currency)), false), + new UninformedImportColumn(GetColumn(cols, nameof(SampleTableModel.CurrencyAsText)), false), + new UninformedImportColumn(GetColumn(cols, nameof(SampleTableModel.CurrencyAsGeneral)), false), + new UninformedImportColumn(GetColumn(cols, nameof(SampleTableModel.Decimal)), false), + new UninformedImportColumn(GetColumn(cols, nameof(SampleTableModel.DecimalAsText)), false), + new UninformedImportColumn(GetColumn(cols, nameof(SampleTableModel.RequiredText)), true), + new UninformedImportColumn(GetColumn(cols, nameof(SampleTableModel.OptionalText)), false), //new ImportColumnTemplate(GetColumn(cols, nameof(SampleTableModel.ListOfStrings)), false), //new ImportColumnTemplate(GetColumn(cols, nameof(SampleTableModel.ListOfStrings)), false), //new ImportColumnTemplate(GetColumn(cols, nameof(SampleTableModel.ListOfStrings)), false), From 03a2aeb392a5d17be72ba387b28640d038ba4de7 Mon Sep 17 00:00:00 2001 From: Dom Schira Date: Mon, 21 Jun 2021 17:51:04 -0700 Subject: [PATCH 03/12] Fixing more things --- ExcelExtensions/Interfaces/IExtensions.cs | 14 +- ExcelExtensions/Models/Column.cs | 17 + ExcelExtensions/Models/ExportColumn.cs | 57 +--- ExcelExtensions/Models/LazyColumn.cs | 8 +- ExcelExtensions/Models/ParseException.cs | 7 +- .../Models/UninformedImportColumn.cs | 4 +- ExcelExtensions/Providers/Extensions.cs | 33 +- .../Providers/Import/Parse/TableParser.cs | 299 +++++++++--------- 8 files changed, 204 insertions(+), 235 deletions(-) diff --git a/ExcelExtensions/Interfaces/IExtensions.cs b/ExcelExtensions/Interfaces/IExtensions.cs index d302754..1c8db62 100644 --- a/ExcelExtensions/Interfaces/IExtensions.cs +++ b/ExcelExtensions/Interfaces/IExtensions.cs @@ -37,7 +37,7 @@ public interface IExtensions /// /// list of ExcelColumnDefinitions /// The max column in the list cells, represented as an - int FindMaxColumn(List columns); + int FindMaxColumn(List columns); /// /// Provides the max row used in a cell sheet based upon Cells. /// @@ -104,12 +104,12 @@ public interface IExtensions /// - KeyValuePair LogDeveloperException(string worksheetName, UninformedImportColumn displayName, string cellAddress, string message, string modelPropertyName); - KeyValuePair LogDeveloperException(string worksheetName, UninformedImportColumn displayName, string cellAddress, int rowNumber, string message); - KeyValuePair LogNullReferenceException(string worksheetName, UninformedImportColumn displayName, string cellAddress, string modelPropertyName); - KeyValuePair LogNullReferenceException(string worksheetName, UninformedImportColumn displayName, string cellAddress, int rowNumber); - KeyValuePair LogCellException(string worksheetName, UninformedImportColumn displayName, string cellAddress, int rowNumber); - KeyValuePair LogCellException(string worksheetName, UninformedImportColumn displayName, string cellAddress, string modelPropertyName); + KeyValuePair LogDeveloperException(string worksheetName, ImportColumn column, string cellAddress, string message, string modelPropertyName); + KeyValuePair LogDeveloperException(string worksheetName, ImportColumn column, string cellAddress, int rowNumber, string message); + KeyValuePair LogNullReferenceException(string worksheetName, ImportColumn column, string cellAddress, string modelPropertyName); + KeyValuePair LogNullReferenceException(string worksheetName, ImportColumn column, string cellAddress, int rowNumber); + KeyValuePair LogCellException(string worksheetName, ImportColumn column, string cellAddress, int rowNumber); + KeyValuePair LogCellException(string worksheetName, ImportColumn column, string cellAddress, string modelPropertyName); } } \ No newline at end of file diff --git a/ExcelExtensions/Models/Column.cs b/ExcelExtensions/Models/Column.cs index 1196280..1ed0b2f 100644 --- a/ExcelExtensions/Models/Column.cs +++ b/ExcelExtensions/Models/Column.cs @@ -1,5 +1,7 @@ // Copyright (c) Dominic Schira . All Rights Reserved. +using ExcelExtensions.Interfaces; +using System; using static ExcelExtensions.Enums.Enums; namespace ExcelExtensions.Models @@ -9,6 +11,12 @@ namespace ExcelExtensions.Models /// public class Column { + private IExtensions excelExtensions; + private Type objType; + private string v1; + private FormatType @string; + private int v2; + public string ModelProperty { get; set; } /// /// Represents the human readable column header name/title @@ -34,5 +42,14 @@ public Column(string modelPropertyName, string displayName, FormatType format, i Format = format; DecimalPrecision = decimalPrecision; } + + public Column(IExtensions excelExtensions, Type objType, string v1, FormatType @string, int v2) + { + this.excelExtensions = excelExtensions; + this.objType = objType; + this.v1 = v1; + this.@string = @string; + this.v2 = v2; + } } } diff --git a/ExcelExtensions/Models/ExportColumn.cs b/ExcelExtensions/Models/ExportColumn.cs index d26c553..bd9e673 100644 --- a/ExcelExtensions/Models/ExportColumn.cs +++ b/ExcelExtensions/Models/ExportColumn.cs @@ -11,62 +11,23 @@ namespace ExcelExtensions.Models /// public class ExportColumn : Column { + + public int ExportColumnNumber { get; } + /// /// Represents the location/letter of the excel column. Ex "C" /// Used for exports and import where we know where to look and are not parsing for new col locations /// - [Obsolete] - public string ExportColumnLetter { get; set; } - public int ExportColumnNumber { get; set; } - /// - /// Represents property name for the mapping object. - /// - public string ModelProperty { get; set; } - /// - /// Represents the human readable column header name/title - /// - public string TableHeaderTitle { get; set; } - /// - /// Represents the format type for the excel object - /// - public FormatType Format { get; set; } - /// - /// Represents the number of decimal places in the output for export - /// - public int? DecimalPrecision { get; set; } - - public ExportColumn() - { + public string? ExportColumnLetter { get; } - } - public ExportColumn(string modelPropertyName, string headerTitle, int columnLetterAsInt, FormatType format, int? decimalPrecision = null) + public ExportColumn(int columnNumber) : base() { - ExportColumnNumber = columnLetterAsInt; - ModelProperty = modelPropertyName; - TableHeaderTitle = headerTitle; - Format = format; - DecimalPrecision = decimalPrecision; + ExportColumnNumber = columnNumber; } - public Column(IExtensions _excelExtensions, Type modelType, string modelPropertyName, FormatType format, string columnLetter = null, int? decimalPrecision = null) - { - _excelExtensions.GetExportModelPropertyNameAndDisplayName(modelType, modelPropertyName, out string textTitle); - if (columnLetter != null) - { - ExportColumnNumber = _excelExtensions.GetColumnNumber(columnLetter); - } - ModelProperty = modelPropertyName; - TableHeaderTitle = textTitle; - Format = format; - DecimalPrecision = decimalPrecision; - } - public Column(IExtensions _excelExtensions, Type modelType, string modelPropertyName, FormatType format, int columnLetterAsInt, int? decimalPrecision = null) + + public ExportColumn(IExtensions excelExtensions, string exportColumnLetter) : this (excelExtensions.GetColumnNumber(exportColumnLetter)) { - _excelExtensions.GetExportModelPropertyNameAndDisplayName(modelType, modelPropertyName, out string textTitle); - ExportColumnNumber = columnLetterAsInt; - ModelProperty = modelPropertyName; - TableHeaderTitle = textTitle; - Format = format; - DecimalPrecision = decimalPrecision; + } } } diff --git a/ExcelExtensions/Models/LazyColumn.cs b/ExcelExtensions/Models/LazyColumn.cs index 4046e2c..c8d37cc 100644 --- a/ExcelExtensions/Models/LazyColumn.cs +++ b/ExcelExtensions/Models/LazyColumn.cs @@ -8,8 +8,14 @@ namespace ExcelExtensions.Models { - public class LazyColumn : Column + /// + /// Eazy button class + /// + public class LazyColumn : UninformedImportColumn { + /// + /// same as in as out + /// public int ColumnLocation { get; set; } public LazyColumn() diff --git a/ExcelExtensions/Models/ParseException.cs b/ExcelExtensions/Models/ParseException.cs index d03dda6..064fe48 100644 --- a/ExcelExtensions/Models/ParseException.cs +++ b/ExcelExtensions/Models/ParseException.cs @@ -66,15 +66,12 @@ public ParseException(string sheetName) { Sheet = sheetName; } - public ParseException(string sheetName, Column column) : this (sheetName) + public ParseException(string sheetName, ImportColumn column) : this (sheetName) { ColumnHeader = column.ModelProperty; //ColumnHeader = column.ColumnHeader; //todo FormatType = column.Format; - } - public ParseException(string sheetName, UninformedImportColumn column) : this (sheetName, column.Column) - { - Severity = (column.IsRequired) ? ParseExceptionSeverity.Error : ParseExceptionSeverity.Warning; + Severity = column.MissingSeverity; } } } diff --git a/ExcelExtensions/Models/UninformedImportColumn.cs b/ExcelExtensions/Models/UninformedImportColumn.cs index 88f66db..0682811 100644 --- a/ExcelExtensions/Models/UninformedImportColumn.cs +++ b/ExcelExtensions/Models/UninformedImportColumn.cs @@ -73,7 +73,9 @@ public InformedImportColumn() : base() } - + public InformedImportColumn(UninformedImportColumn column1, int column2) + { + } } diff --git a/ExcelExtensions/Providers/Extensions.cs b/ExcelExtensions/Providers/Extensions.cs index 872bd34..d8a9068 100644 --- a/ExcelExtensions/Providers/Extensions.cs +++ b/ExcelExtensions/Providers/Extensions.cs @@ -18,23 +18,23 @@ namespace ExcelExtensions.Providers public class Extensions : IExtensions { #region developer exceptions - public KeyValuePair LogDeveloperException(string worksheetName, UninformedImportColumn importColumn, string cellAddress, string message, string modelPropertyName) + public KeyValuePair LogDeveloperException(string worksheetName, ImportColumn column, string cellAddress, string message, string modelPropertyName) { - ParseException parseException = LogDeveloperExceptionParseException(worksheetName, importColumn, cellAddress, message); + ParseException parseException = LogDeveloperExceptionParseException(worksheetName, column, cellAddress, message); return new KeyValuePair(modelPropertyName, parseException); } - public KeyValuePair LogDeveloperException(string worksheetName, UninformedImportColumn importColumn, string cellAddress, int rowNumber, string message) + public KeyValuePair LogDeveloperException(string worksheetName, ImportColumn importColumn, string cellAddress, int rowNumber, string message) { ParseException parseException = LogDeveloperExceptionParseException(worksheetName, importColumn, cellAddress, message); return new KeyValuePair(rowNumber, parseException); } - private ParseException LogDeveloperExceptionParseException(string worksheetName, UninformedImportColumn importColumn, string cellAddress, string exeptionMessage) + private ParseException LogDeveloperExceptionParseException(string worksheetName, ImportColumn importColumn, string cellAddress, string exeptionMessage) { //ParseException parseException = new(worksheetName, displayName, cellAddress, null, "An error occurred when trying to set the property info. The error is: " + message) - ParseException parseException = new(worksheetName, importColumn.Column) + ParseException parseException = new(worksheetName, importColumn) { ColumnLetter = GetColumnLetter(cellAddress), Message = $"An error occurred when trying to set the property info. The error is: {exeptionMessage}", @@ -45,21 +45,21 @@ private ParseException LogDeveloperExceptionParseException(string worksheetName, return parseException; } - public KeyValuePair LogNullReferenceException(string worksheetName, UninformedImportColumn displayName, string cellAddress, string modelPropertyName) + public KeyValuePair LogNullReferenceException(string worksheetName, ImportColumn column, string cellAddress, string modelPropertyName) { - ParseException parseException = LogNullReferenceExceptionParseException(worksheetName, displayName, cellAddress); + ParseException parseException = LogNullReferenceExceptionParseException(worksheetName, column, cellAddress); return new KeyValuePair(modelPropertyName, parseException); } - public KeyValuePair LogNullReferenceException(string worksheetName, UninformedImportColumn displayName, string cellAddress, int rowNumber) + public KeyValuePair LogNullReferenceException(string worksheetName, ImportColumn displayName, string cellAddress, int rowNumber) { ParseException parseException = LogNullReferenceExceptionParseException(worksheetName, displayName, cellAddress); return new KeyValuePair(rowNumber, parseException); } - private ParseException LogNullReferenceExceptionParseException(string worksheetName, UninformedImportColumn column, string cellAddress) + private ParseException LogNullReferenceExceptionParseException(string worksheetName, ImportColumn column, string cellAddress) { ParseException parseException = new(worksheetName, column) { @@ -71,21 +71,21 @@ private ParseException LogNullReferenceExceptionParseException(string worksheetN return parseException; } - public KeyValuePair LogCellException(string worksheetName, UninformedImportColumn displayName, string cellAddress, string modelPropertyName) + public KeyValuePair LogCellException(string worksheetName, ImportColumn column, string cellAddress, string modelPropertyName) { - ParseException parseException = LogCellExceptionParseException(worksheetName, displayName, cellAddress); + ParseException parseException = LogCellExceptionParseException(worksheetName, column, cellAddress); return new KeyValuePair(modelPropertyName, parseException); } - public KeyValuePair LogCellException(string worksheetName, UninformedImportColumn displayName, string cellAddress, int rowNumber) + public KeyValuePair LogCellException(string worksheetName, ImportColumn column, string cellAddress, int rowNumber) { - ParseException parseException = LogCellExceptionParseException(worksheetName, displayName, cellAddress); + ParseException parseException = LogCellExceptionParseException(worksheetName, column, cellAddress); return new KeyValuePair(rowNumber, parseException); } - private ParseException LogCellExceptionParseException(string worksheetName, UninformedImportColumn column, string cellAddress) + private ParseException LogCellExceptionParseException(string worksheetName, ImportColumn column, string cellAddress) { ParseException parseException = new(worksheetName, column) { @@ -196,8 +196,9 @@ public int FindMaxRow(List cells) /// - public int FindMaxColumn(List columns) - => columns.Select(column => GetColumnNumber(column.ExportColumnLetter)).Max(); + public int FindMaxColumn(List columns) + //TODO + => columns.Select(column => column.ExportColumnNumber).Max(); /// public string AddDecimalPlacesToFormat(Column column, string noDecimals) diff --git a/ExcelExtensions/Providers/Import/Parse/TableParser.cs b/ExcelExtensions/Providers/Import/Parse/TableParser.cs index a9ce54d..2afd268 100644 --- a/ExcelExtensions/Providers/Import/Parse/TableParser.cs +++ b/ExcelExtensions/Providers/Import/Parse/TableParser.cs @@ -41,10 +41,8 @@ public ParsedTable UninformedParseTable(List columns, } int rowScanCount = 0; - List columnsWithCellAddresses = CheckForMissingColumnNumbersInImportColumnTemplates(columns); - //Check for each of the expected columns in - ScanForHeaderRow(columnsWithCellAddresses, ref workSheet, ref headerRowNumber, maxScanHeaderRowThreashold, ref rowScanCount); + List columnsWithCellAddresses = ScanForHeaderRow(columns, ref workSheet, ref headerRowNumber, maxScanHeaderRowThreashold, ref rowScanCount); if (CheckMissingScannedColumns(headerRowNumber, maxScanHeaderRowThreashold, rowScanCount, columns)) { @@ -55,17 +53,6 @@ public ParsedTable UninformedParseTable(List columns, return ParseRows(columnsWithCellAddresses, workSheet, headerRowNumber); } - public ParsedTable InformedParseTable(List columns, ExcelWorksheet workSheet, int headerRowNumber = 1) - { - if (_excelExtensions is null) - { - throw new ArgumentNullException(nameof(IExtensions), $"Make sure when TableParser is constructed that {nameof(IExtensions)} gets passed in."); - } - - List columnsWithCellAddresses = CheckForMissingColumnNumbersInImportColumnTemplates(columns); - - return InformedParseTable(columnsWithCellAddresses, workSheet, headerRowNumber); - } public ParsedTable InformedParseTable(List columns, ExcelWorksheet workSheet, int headerRowNumber = 1) { if (_excelExtensions is null) @@ -149,20 +136,6 @@ private ParsedTable ParseRows(List columnsWithCellAddre return _parseResults; } - /// - /// Get the cell address using the extension from the data the user provided in the import map - /// - /// - private List CheckForMissingColumnNumbersInImportColumnTemplates(List columns) - { - List columnsWithCellAddresses = new(); - foreach (UninformedImportColumn item in columns) - { - columnsWithCellAddresses.Add(new InformedImportColumn(_excelExtensions, item)); - } - return columnsWithCellAddresses; - } - /// /// Try to find the header row of the imported data. If the fields are not found, keep scanning the next row until the row max threshold is reached. @@ -173,8 +146,9 @@ private List CheckForMissingColumnNumbersInImportColumnTem /// /// /// There must be at least one required field. - private void ScanForHeaderRow(List columns, ref ExcelWorksheet workSheet, ref int headerRowNumber, int maxScanHeaderRowThreashold, ref int rowScanCount) + private List ScanForHeaderRow(List columns, ref ExcelWorksheet workSheet, ref int headerRowNumber, int maxScanHeaderRowThreashold, ref int rowScanCount) { + List informedColumns = new(); do { //Make sure the errors are clear first @@ -182,7 +156,7 @@ private void ScanForHeaderRow(List columns, ref ExcelWorks _requiredFieldsColumnLocations.Clear(); //reset previous rows number - FindColumnNamesAndCheckRequiredColumns(columns, ref workSheet, ref headerRowNumber); + informedColumns = FindColumnNamesAndCheckRequiredColumns(columns, ref workSheet, ref headerRowNumber); List requiredErrors = _parseResults.Exceptions.Where(x => x.Value.ExceptionType != ParseExceptionType.OptionalColumnMissing).Select(x => x.Value).ToList(); @@ -206,6 +180,8 @@ private void ScanForHeaderRow(List columns, ref ExcelWorks } //While we have no missing required columns and while we are not at max scan while (_parseResults.Exceptions.Where(x => x.Value.ExceptionType != ParseExceptionType.OptionalColumnMissing).Any() && rowScanCount != maxScanHeaderRowThreashold); + + return informedColumns; } /// @@ -261,23 +237,28 @@ private bool CheckMissingScannedColumns(int headerRowId, int maxScanHeaderRowThr /// /// /// - private void FindColumnNamesAndCheckRequiredColumns(List columns, ref ExcelWorksheet workSheet, ref int headerRowId) + private List FindColumnNamesAndCheckRequiredColumns(List columns, ref ExcelWorksheet workSheet, ref int headerRowId) { - foreach (InformedImportColumn coltemplate in columns) + List informedColumns = new(); + + foreach (UninformedImportColumn column in columns) { + InformedImportColumn informedImportColumn = null; + foreach (ExcelRangeBase firstRowCell in workSheet.Cells[headerRowId, workSheet.Dimension.Start.Column, headerRowId, workSheet.Dimension.End.Column]) { - if (coltemplate.DisplayNameOptions.Any(x => x.Equals(firstRowCell.Text, StringComparison.OrdinalIgnoreCase))) + if (column.DisplayNameOptions.Any(x => x.Equals(firstRowCell.Text, StringComparison.OrdinalIgnoreCase))) { - coltemplate.ImportColumnNumber = firstRowCell.Start.Column; + informedImportColumn = new InformedImportColumn(column, firstRowCell.Start.Column); + informedColumns.Add(informedImportColumn); continue; } } - if (coltemplate.IsRequired && coltemplate.ImportColumnNumber == 0) + if (column.IsRequired && informedImportColumn == null) { - ParseException parseException = new(workSheet.Name, coltemplate.Column) + ParseException parseException = new(workSheet.Name, column) { ExceptionType = ParseExceptionType.RequiredColumnMissing, Severity = ParseExceptionSeverity.Error, @@ -285,9 +266,9 @@ private void FindColumnNamesAndCheckRequiredColumns(List c }; _parseResults.Exceptions.Add(new KeyValuePair(headerRowId, parseException)); } - else if (coltemplate.ImportColumnNumber == 0 && coltemplate.IsRequired == false) + else if (informedImportColumn == null && column.IsRequired == false) { - ParseException parseException = new(workSheet.Name, coltemplate.Column) + ParseException parseException = new(workSheet.Name, column) { ExceptionType = ParseExceptionType.OptionalColumnMissing, Severity = ParseExceptionSeverity.Warning, @@ -297,12 +278,14 @@ private void FindColumnNamesAndCheckRequiredColumns(List c } - if (coltemplate.IsRequired == true) + if (column.IsRequired == true) { - _requiredFieldsColumnLocations.Add(_excelExtensions.GetColumnLetter(coltemplate.ImportColumnNumber)); + _requiredFieldsColumnLocations.Add(_excelExtensions.GetColumnLetter(informedImportColumn.ImportColumnNumber)); } } + + return informedColumns; } /// @@ -310,12 +293,12 @@ private void FindColumnNamesAndCheckRequiredColumns(List c /// /// /// - /// + /// /// /// Will throw errors. disable them when debugging through this dll file. - private void ParseCell(ExcelWorksheet workSheet, int rowNumber, UninformedImportColumn coltemplate, ExcelRange cell) + private void ParseCell(ExcelWorksheet workSheet, int rowNumber, ImportColumn column, ExcelRange cell) { - switch (coltemplate.Column.Format) + switch (column.Format) { case FormatType.Bool: { @@ -324,15 +307,15 @@ private void ParseCell(ExcelWorksheet workSheet, int rowNumber, UninformedImport //try to parse bool value = _parser.ParseBool(cell); - SetValue(workSheet, rowNumber, coltemplate, cell, value); + SetValue(workSheet, rowNumber, column, cell, value); } catch (NullReferenceException) { - _singleRowErrors.Add(_excelExtensions.LogNullReferenceException(workSheet.Name, coltemplate, cell.Address, rowNumber)); + _singleRowErrors.Add(_excelExtensions.LogNullReferenceException(workSheet.Name, column, cell.Address, rowNumber)); } catch (Exception) { - _singleRowErrors.Add(_excelExtensions.LogCellException(workSheet.Name, coltemplate, cell.Address, rowNumber)); + _singleRowErrors.Add(_excelExtensions.LogCellException(workSheet.Name, column, cell.Address, rowNumber)); } break; } @@ -342,15 +325,15 @@ private void ParseCell(ExcelWorksheet workSheet, int rowNumber, UninformedImport { decimal? value = _parser.ParseCurrency(cell); - SetValue(workSheet, rowNumber, coltemplate, cell, value); + SetValue(workSheet, rowNumber, column, cell, value); } catch (NullReferenceException) { - _singleRowErrors.Add(_excelExtensions.LogNullReferenceException(workSheet.Name, coltemplate, cell.Address, rowNumber)); + _singleRowErrors.Add(_excelExtensions.LogNullReferenceException(workSheet.Name, column, cell.Address, rowNumber)); } catch (Exception) { - _singleRowErrors.Add(_excelExtensions.LogCellException(workSheet.Name, coltemplate, cell.Address, rowNumber)); + _singleRowErrors.Add(_excelExtensions.LogCellException(workSheet.Name, column, cell.Address, rowNumber)); } break; } @@ -359,16 +342,16 @@ private void ParseCell(ExcelWorksheet workSheet, int rowNumber, UninformedImport try { DateTime? date = _parser.ParseDate(cell); - SetValue(workSheet, rowNumber, coltemplate, cell, date); + SetValue(workSheet, rowNumber, column, cell, date); } catch (NullReferenceException) { - _singleRowErrors.Add(_excelExtensions.LogNullReferenceException(workSheet.Name, coltemplate, cell.Address, rowNumber)); + _singleRowErrors.Add(_excelExtensions.LogNullReferenceException(workSheet.Name, column, cell.Address, rowNumber)); } catch (Exception) { - _singleRowErrors.Add(_excelExtensions.LogCellException(workSheet.Name, coltemplate, cell.Address, rowNumber)); + _singleRowErrors.Add(_excelExtensions.LogCellException(workSheet.Name, column, cell.Address, rowNumber)); } break; } @@ -378,15 +361,15 @@ private void ParseCell(ExcelWorksheet workSheet, int rowNumber, UninformedImport try { TimeSpan? duration = _parser.ParseTimeSpan(cell); - SetValue(workSheet, rowNumber, coltemplate, cell, duration); + SetValue(workSheet, rowNumber, column, cell, duration); } catch (NullReferenceException) { - _singleRowErrors.Add(_excelExtensions.LogNullReferenceException(workSheet.Name, coltemplate, cell.Address, rowNumber)); + _singleRowErrors.Add(_excelExtensions.LogNullReferenceException(workSheet.Name, column, cell.Address, rowNumber)); } catch (Exception) { - _singleRowErrors.Add(_excelExtensions.LogCellException(workSheet.Name, coltemplate, cell.Address, rowNumber)); + _singleRowErrors.Add(_excelExtensions.LogCellException(workSheet.Name, column, cell.Address, rowNumber)); } break; } @@ -395,15 +378,15 @@ private void ParseCell(ExcelWorksheet workSheet, int rowNumber, UninformedImport try { decimal? value = _parser.ParsePercent(cell); - SetValue(workSheet, rowNumber, coltemplate, cell, value); + SetValue(workSheet, rowNumber, column, cell, value); } catch (NullReferenceException) { - _singleRowErrors.Add(_excelExtensions.LogNullReferenceException(workSheet.Name, coltemplate, cell.Address, rowNumber)); + _singleRowErrors.Add(_excelExtensions.LogNullReferenceException(workSheet.Name, column, cell.Address, rowNumber)); } catch (Exception) { - _singleRowErrors.Add(_excelExtensions.LogCellException(workSheet.Name, coltemplate, cell.Address, rowNumber)); + _singleRowErrors.Add(_excelExtensions.LogCellException(workSheet.Name, column, cell.Address, rowNumber)); } break; } @@ -412,15 +395,15 @@ private void ParseCell(ExcelWorksheet workSheet, int rowNumber, UninformedImport try { double? value = _parser.ParseDouble(cell); - SetValue(workSheet, rowNumber, coltemplate, cell, value); + SetValue(workSheet, rowNumber, column, cell, value); } catch (NullReferenceException) { - _singleRowErrors.Add(_excelExtensions.LogNullReferenceException(workSheet.Name, coltemplate, cell.Address, rowNumber)); + _singleRowErrors.Add(_excelExtensions.LogNullReferenceException(workSheet.Name, column, cell.Address, rowNumber)); } catch (Exception) { - _singleRowErrors.Add(_excelExtensions.LogCellException(workSheet.Name, coltemplate, cell.Address, rowNumber)); + _singleRowErrors.Add(_excelExtensions.LogCellException(workSheet.Name, column, cell.Address, rowNumber)); } break; } @@ -429,120 +412,122 @@ private void ParseCell(ExcelWorksheet workSheet, int rowNumber, UninformedImport try { decimal? value = _parser.ParseDecimal(cell); - SetValue(workSheet, rowNumber, coltemplate, cell, value); - } - catch (NullReferenceException) - { - _singleRowErrors.Add(_excelExtensions.LogNullReferenceException(workSheet.Name, coltemplate, cell.Address, rowNumber)); - } - catch (Exception) - { - _singleRowErrors.Add(_excelExtensions.LogCellException(workSheet.Name, coltemplate, cell.Address, rowNumber)); - } - break; - } - case FormatType.DecimalList: - { - try - { - decimal? val = null; - try - { - val = _parser.ParseDecimal(cell); - } - catch (NullReferenceException) - { - //Fine if this is null. Lets keep going - } - - - // get info about property - PropertyInfo modelPropertyInfo = _model.GetType().GetProperty(coltemplate.Column.ModelProperty); - - var list = modelPropertyInfo.GetValue(_model); - Dictionary decimalList; - if (list == null) //this is the first item in the list so we need to init the list. - { - decimalList = new Dictionary(); - } - else - { - decimalList = (Dictionary)list; - } - - decimalList.Add(coltemplate.DisplayNameOptions[0], val); - - modelPropertyInfo.SetValue(_model, decimalList, null); + SetValue(workSheet, rowNumber, column, cell, value); } catch (NullReferenceException) { - _singleRowErrors.Add(_excelExtensions.LogNullReferenceException(workSheet.Name, coltemplate, cell.Address, rowNumber)); + _singleRowErrors.Add(_excelExtensions.LogNullReferenceException(workSheet.Name, column, cell.Address, rowNumber)); } catch (Exception) { - _singleRowErrors.Add(_excelExtensions.LogCellException(workSheet.Name, coltemplate, cell.Address, rowNumber)); + _singleRowErrors.Add(_excelExtensions.LogCellException(workSheet.Name, column, cell.Address, rowNumber)); } break; } + //TODO + //case FormatType.DecimalList: + // { + // try + // { + // decimal? val = null; + // try + // { + // val = _parser.ParseDecimal(cell); + // } + // catch (NullReferenceException) + // { + // //Fine if this is null. Lets keep going + // } + + + // // get info about property + // PropertyInfo modelPropertyInfo = _model.GetType().GetProperty(column.ModelProperty); + + // var list = modelPropertyInfo.GetValue(_model); + // Dictionary decimalList; + // if (list == null) //this is the first item in the list so we need to init the list. + // { + // decimalList = new Dictionary(); + // } + // else + // { + // decimalList = (Dictionary)list; + // } + + // decimalList.Add(column.DisplayNameOptions[0], val); + + // modelPropertyInfo.SetValue(_model, decimalList, null); + // } + // catch (NullReferenceException) + // { + // _singleRowErrors.Add(_excelExtensions.LogNullReferenceException(workSheet.Name, column, cell.Address, rowNumber)); + // } + // catch (Exception) + // { + // _singleRowErrors.Add(_excelExtensions.LogCellException(workSheet.Name, column, cell.Address, rowNumber)); + // } + // break; + // } case FormatType.Int: { try { int? value = _parser.ParseInt(cell); - SetValue(workSheet, rowNumber, coltemplate, cell, value); - } - catch (NullReferenceException) - { - _singleRowErrors.Add(_excelExtensions.LogNullReferenceException(workSheet.Name, coltemplate, cell.Address, rowNumber)); - } - catch (Exception) - { - _singleRowErrors.Add(_excelExtensions.LogCellException(workSheet.Name, coltemplate, cell.Address, rowNumber)); - } - break; - } - case FormatType.StringList: - { - try - { - _parser.CheckIfCellIsNullOrEmpty(cell, "a string list"); - - string cellVal = cell.Value.ToString().Trim(); - - if (string.IsNullOrEmpty(cellVal) && !string.IsNullOrEmpty(cell.Formula)) - { - //We have a formula which is setting the field to blank instead of null - throw new NullReferenceException(); - } - - // get info about property - PropertyInfo modelPropertyInfo = _model.GetType().GetProperty(coltemplate.Column.ModelProperty); - - object list = modelPropertyInfo.GetValue(_model); - Dictionary stringlist; - if (list == null) //this is the first item in the list so we need to init the list. - { - stringlist = new Dictionary(); - } - else - { - stringlist = (Dictionary)list; - } - - stringlist.Add(coltemplate.DisplayNameOptions[0], cellVal); - - modelPropertyInfo.SetValue(_model, stringlist, null); + SetValue(workSheet, rowNumber, column, cell, value); } catch (NullReferenceException) { - _singleRowErrors.Add(_excelExtensions.LogNullReferenceException(workSheet.Name, coltemplate, cell.Address, rowNumber)); + _singleRowErrors.Add(_excelExtensions.LogNullReferenceException(workSheet.Name, column, cell.Address, rowNumber)); } catch (Exception) { - _singleRowErrors.Add(_excelExtensions.LogCellException(workSheet.Name, coltemplate, cell.Address, rowNumber)); + _singleRowErrors.Add(_excelExtensions.LogCellException(workSheet.Name, column, cell.Address, rowNumber)); } break; } + //TODO + //case FormatType.StringList: + // { + // try + // { + // _parser.CheckIfCellIsNullOrEmpty(cell, "a string list"); + + // string cellVal = cell.Value.ToString().Trim(); + + // if (string.IsNullOrEmpty(cellVal) && !string.IsNullOrEmpty(cell.Formula)) + // { + // //We have a formula which is setting the field to blank instead of null + // throw new NullReferenceException(); + // } + + // // get info about property + // PropertyInfo modelPropertyInfo = _model.GetType().GetProperty(column.ModelProperty); + + // object list = modelPropertyInfo.GetValue(_model); + // Dictionary stringlist; + // if (list == null) //this is the first item in the list so we need to init the list. + // { + // stringlist = new Dictionary(); + // } + // else + // { + // stringlist = (Dictionary)list; + // } + + // stringlist.Add(column.DisplayNameOptions[0], cellVal); + + // modelPropertyInfo.SetValue(_model, stringlist, null); + // } + // catch (NullReferenceException) + // { + // _singleRowErrors.Add(_excelExtensions.LogNullReferenceException(workSheet.Name, column, cell.Address, rowNumber)); + // } + // catch (Exception) + // { + // _singleRowErrors.Add(_excelExtensions.LogCellException(workSheet.Name, column, cell.Address, rowNumber)); + // } + // break; + // } case FormatType.String: //uses default default: @@ -550,15 +535,15 @@ private void ParseCell(ExcelWorksheet workSheet, int rowNumber, UninformedImport try { string value = _parser.ParseString(cell); - SetValue(workSheet, rowNumber, coltemplate, cell, value); + SetValue(workSheet, rowNumber, column, cell, value); } catch (NullReferenceException) { - _singleRowErrors.Add(_excelExtensions.LogNullReferenceException(workSheet.Name, coltemplate, cell.Address, rowNumber)); + _singleRowErrors.Add(_excelExtensions.LogNullReferenceException(workSheet.Name, column, cell.Address, rowNumber)); } catch (Exception) { - _singleRowErrors.Add(_excelExtensions.LogCellException(workSheet.Name, coltemplate, cell.Address, rowNumber)); + _singleRowErrors.Add(_excelExtensions.LogCellException(workSheet.Name, column, cell.Address, rowNumber)); } break; } @@ -573,12 +558,12 @@ private void ParseCell(ExcelWorksheet workSheet, int rowNumber, UninformedImport /// /// /// - private void SetValue(ExcelWorksheet workSheet, int rowNumber, UninformedImportColumn coltemplate, ExcelRange cell, object value) + private void SetValue(ExcelWorksheet workSheet, int rowNumber, ImportColumn coltemplate, ExcelRange cell, object value) { try { // get info about property - PropertyInfo modelPropertyInfo = _model.GetType().GetProperty(coltemplate.Column.ModelProperty); + PropertyInfo modelPropertyInfo = _model.GetType().GetProperty(coltemplate.ModelProperty); // set value of property modelPropertyInfo.SetValue(_model, value, null); From 6c67611a9657b7647c5ca00e9bf910775200eb9c Mon Sep 17 00:00:00 2001 From: Dom Schira Date: Mon, 21 Jun 2021 18:05:57 -0700 Subject: [PATCH 04/12] name spaces --- .../Interfaces/Export/IExporter.cs | 11 ++- ExcelExtensions/Interfaces/IExtensions.cs | 1 + .../Import/IFileAndSheetValidatior.cs | 1 + .../Interfaces/Import/Parse/ITableParser.cs | 3 +- ExcelExtensions/Models/{ => Cells}/Cell.cs | 0 .../Models/{ => Columns}/Column.cs | 0 .../{ => Columns/Export}/ExportColumn.cs | 12 +-- .../Import}/ColumnWithSeverity.cs | 0 .../Models/Columns/Import/ImportColumn.cs | 31 +++++++ .../Columns/Import/UninformedImportColumn.cs | 43 ++++++++++ .../Models/Columns/InformedColumn.cs | 32 ++++++++ ExcelExtensions/Models/{ => Export}/Style.cs | 2 +- .../Models/{ => Import}/ImportException.cs | 2 +- .../Models/{ => Import}/ParseException.cs | 0 .../Models/{ => Import}/ParsedTable.cs | 0 ExcelExtensions/Models/LazyColumn.cs | 26 ------ .../Models/UninformedImportColumn.cs | 82 ------------------- ExcelExtensions/Providers/Export/Exporter.cs | 21 ++--- ExcelExtensions/Providers/Extensions.cs | 3 +- .../Import/FileAndSheetValidatior.cs | 1 + .../Providers/Import/ImportMapFactory.cs | 4 +- .../Providers/Import/Parse/TableParser.cs | 33 ++++---- WebApplication/Controllers/HomeController.cs | 2 +- WebApplication/Providers/SampleProvider.cs | 2 + 24 files changed, 159 insertions(+), 153 deletions(-) rename ExcelExtensions/Models/{ => Cells}/Cell.cs (100%) rename ExcelExtensions/Models/{ => Columns}/Column.cs (100%) rename ExcelExtensions/Models/{ => Columns/Export}/ExportColumn.cs (71%) rename ExcelExtensions/Models/{ => Columns/Import}/ColumnWithSeverity.cs (100%) create mode 100644 ExcelExtensions/Models/Columns/Import/ImportColumn.cs create mode 100644 ExcelExtensions/Models/Columns/Import/UninformedImportColumn.cs create mode 100644 ExcelExtensions/Models/Columns/InformedColumn.cs rename ExcelExtensions/Models/{ => Export}/Style.cs (96%) rename ExcelExtensions/Models/{ => Import}/ImportException.cs (97%) rename ExcelExtensions/Models/{ => Import}/ParseException.cs (100%) rename ExcelExtensions/Models/{ => Import}/ParsedTable.cs (100%) delete mode 100644 ExcelExtensions/Models/LazyColumn.cs delete mode 100644 ExcelExtensions/Models/UninformedImportColumn.cs diff --git a/ExcelExtensions/Interfaces/Export/IExporter.cs b/ExcelExtensions/Interfaces/Export/IExporter.cs index dd7471c..0e7423b 100644 --- a/ExcelExtensions/Interfaces/Export/IExporter.cs +++ b/ExcelExtensions/Interfaces/Export/IExporter.cs @@ -1,6 +1,7 @@ // Copyright (c) Dominic Schira . All Rights Reserved. using ExcelExtensions.Models; +using ExcelExtensions.Models.Export; using OfficeOpenXml; using System.Collections.Generic; using static ExcelExtensions.Enums.Enums; @@ -12,6 +13,8 @@ namespace ExcelExtensions.Interfaces.Export /// public interface IExporter { + //TODO: fix for LazyColumn + /// /// Export a table to an /// @@ -21,7 +24,7 @@ public interface IExporter /// /// /// - void ExportTable(ref ExcelWorksheet sheet, List rows, List columnDefinitions, Style style, int headerRow = 1); + void ExportTable(ref ExcelWorksheet sheet, List rows, List columnDefinitions, Style style, int headerRow = 1); /// /// Export list of columns to an /// @@ -31,13 +34,13 @@ public interface IExporter /// /// /// - void ExportColumns(ref ExcelWorksheet sheet, List rows, List columns, int headerRow = 1, string displayNameAdditionalText = null); + void ExportColumns(ref ExcelWorksheet sheet, List rows, List columns, int headerRow = 1, string displayNameAdditionalText = null); /// /// Format the column of an /// /// /// - void FormatColumn(Column column, ref ExcelWorksheet sheet); + void FormatColumn(ExportColumn column, ref ExcelWorksheet sheet); /// /// Format the column of an /// @@ -64,6 +67,6 @@ public interface IExporter /// /// /// - void StyleTableHeaderRow(List columns, ref ExcelWorksheet sheet, Style style, int? startrow = null); + void StyleTableHeaderRow(List columns, ref ExcelWorksheet sheet, Style style, int? startrow = null); } } \ No newline at end of file diff --git a/ExcelExtensions/Interfaces/IExtensions.cs b/ExcelExtensions/Interfaces/IExtensions.cs index 1c8db62..474cc9d 100644 --- a/ExcelExtensions/Interfaces/IExtensions.cs +++ b/ExcelExtensions/Interfaces/IExtensions.cs @@ -1,6 +1,7 @@ // Copyright (c) Dominic Schira . All Rights Reserved. using ExcelExtensions.Models; +using ExcelExtensions.Models.Columns.Import; using System; using System.Collections.Generic; diff --git a/ExcelExtensions/Interfaces/Import/IFileAndSheetValidatior.cs b/ExcelExtensions/Interfaces/Import/IFileAndSheetValidatior.cs index df2959e..321e615 100644 --- a/ExcelExtensions/Interfaces/Import/IFileAndSheetValidatior.cs +++ b/ExcelExtensions/Interfaces/Import/IFileAndSheetValidatior.cs @@ -1,6 +1,7 @@ // Copyright (c) Dominic Schira . All Rights Reserved. using ExcelExtensions.Models; +using ExcelExtensions.Models.Import; using OfficeOpenXml; namespace ExcelExtensions.Interfaces.Import diff --git a/ExcelExtensions/Interfaces/Import/Parse/ITableParser.cs b/ExcelExtensions/Interfaces/Import/Parse/ITableParser.cs index 524d22e..6000b64 100644 --- a/ExcelExtensions/Interfaces/Import/Parse/ITableParser.cs +++ b/ExcelExtensions/Interfaces/Import/Parse/ITableParser.cs @@ -1,6 +1,7 @@ // Copyright (c) Dominic Schira . All Rights Reserved. using ExcelExtensions.Models; +using ExcelExtensions.Models.Columns; using OfficeOpenXml; using System.Collections.Generic; @@ -13,6 +14,6 @@ namespace ExcelExtensions.Interfaces.Import.Parse public interface ITableParser { ParsedTable UninformedParseTable(List columns, ExcelWorksheet workSheet, int headerRowNumber = 1, int maxScanHeaderRowThreashold = 100); - ParsedTable InformedParseTable(List columns, ExcelWorksheet workSheet, int headerRowNumber = 1); + ParsedTable InformedParseTable(List columns, ExcelWorksheet workSheet, int headerRowNumber = 1); } } diff --git a/ExcelExtensions/Models/Cell.cs b/ExcelExtensions/Models/Cells/Cell.cs similarity index 100% rename from ExcelExtensions/Models/Cell.cs rename to ExcelExtensions/Models/Cells/Cell.cs diff --git a/ExcelExtensions/Models/Column.cs b/ExcelExtensions/Models/Columns/Column.cs similarity index 100% rename from ExcelExtensions/Models/Column.cs rename to ExcelExtensions/Models/Columns/Column.cs diff --git a/ExcelExtensions/Models/ExportColumn.cs b/ExcelExtensions/Models/Columns/Export/ExportColumn.cs similarity index 71% rename from ExcelExtensions/Models/ExportColumn.cs rename to ExcelExtensions/Models/Columns/Export/ExportColumn.cs index bd9e673..5424347 100644 --- a/ExcelExtensions/Models/ExportColumn.cs +++ b/ExcelExtensions/Models/Columns/Export/ExportColumn.cs @@ -1,19 +1,15 @@ // Copyright (c) Dominic Schira . All Rights Reserved. using ExcelExtensions.Interfaces; -using System; -using static ExcelExtensions.Enums.Enums; +using ExcelExtensions.Models.Columns; namespace ExcelExtensions.Models { /// /// Represents an excel column /// - public class ExportColumn : Column + public class ExportColumn : InformedColumn { - - public int ExportColumnNumber { get; } - /// /// Represents the location/letter of the excel column. Ex "C" /// Used for exports and import where we know where to look and are not parsing for new col locations @@ -22,10 +18,10 @@ public class ExportColumn : Column public ExportColumn(int columnNumber) : base() { - ExportColumnNumber = columnNumber; + ColumnNumber = columnNumber; } - public ExportColumn(IExtensions excelExtensions, string exportColumnLetter) : this (excelExtensions.GetColumnNumber(exportColumnLetter)) + public ExportColumn(IExtensions excelExtensions, string exportColumnLetter) : this(excelExtensions.GetColumnNumber(exportColumnLetter)) { } diff --git a/ExcelExtensions/Models/ColumnWithSeverity.cs b/ExcelExtensions/Models/Columns/Import/ColumnWithSeverity.cs similarity index 100% rename from ExcelExtensions/Models/ColumnWithSeverity.cs rename to ExcelExtensions/Models/Columns/Import/ColumnWithSeverity.cs diff --git a/ExcelExtensions/Models/Columns/Import/ImportColumn.cs b/ExcelExtensions/Models/Columns/Import/ImportColumn.cs new file mode 100644 index 0000000..4493dd1 --- /dev/null +++ b/ExcelExtensions/Models/Columns/Import/ImportColumn.cs @@ -0,0 +1,31 @@ +// Copyright (c) Dominic Schira . All Rights Reserved. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static ExcelExtensions.Enums.Enums; + +namespace ExcelExtensions.Models.Columns.Import +{ + public class ImportColumn : ColumnWithSeverity + { + public bool IsRequired { get; set; } + + public ImportColumn() : base() + { + IsRequired = MissingSeverity == ParseExceptionSeverity.Error; + } + + public ImportColumn(Column column, bool required) : base(column, required ? ParseExceptionSeverity.Error : ParseExceptionSeverity.Warning) + { + + } + public ImportColumn(string modelPropertyName, string displayName, FormatType format, bool required = true, int? decimalPrecision = null) : + base(modelPropertyName, displayName, format, required ? ParseExceptionSeverity.Error : ParseExceptionSeverity.Warning, decimalPrecision) + { + + } + } +} diff --git a/ExcelExtensions/Models/Columns/Import/UninformedImportColumn.cs b/ExcelExtensions/Models/Columns/Import/UninformedImportColumn.cs new file mode 100644 index 0000000..ee2ec6e --- /dev/null +++ b/ExcelExtensions/Models/Columns/Import/UninformedImportColumn.cs @@ -0,0 +1,43 @@ +// Copyright (c) Dominic Schira . All Rights Reserved. + +using ExcelExtensions.Interfaces; +using ExcelExtensions.Models.Columns.Import; +using System; +using System.Collections.Generic; +using System.Linq; +using static ExcelExtensions.Enums.Enums; + +namespace ExcelExtensions.Models +{ + + /// + /// SCAN AND PARSE + /// + public class UninformedImportColumn : ImportColumn + { + /// + /// Represent the list of options for the header name + /// Used for parseing + /// + public List DisplayNameOptions { get; set; } + public UninformedImportColumn() + { + + } + + + /// + /// Adds the header name/title from the column + /// + /// + /// + /// Optional names to search for + public UninformedImportColumn(Column column, bool required, List columnOptions = null) : base(column, required) + { + DisplayNameOptions = columnOptions ?? new List(); + DisplayNameOptions.Add(column.DisplayName); + MissingSeverity = required ? ParseExceptionSeverity.Error : ParseExceptionSeverity.Warning; + } + } + +} diff --git a/ExcelExtensions/Models/Columns/InformedColumn.cs b/ExcelExtensions/Models/Columns/InformedColumn.cs new file mode 100644 index 0000000..11662ff --- /dev/null +++ b/ExcelExtensions/Models/Columns/InformedColumn.cs @@ -0,0 +1,32 @@ +// Copyright (c) Dominic Schira . All Rights Reserved. + +using ExcelExtensions.Models.Columns.Import; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ExcelExtensions.Models.Columns +{ + /// + /// JUST PARSE + /// + public class InformedColumn : ColumnWithSeverity + { + /// + /// used as a pointer for where we are importing and saved if we are looking for a column that doesn't have a letter + /// This will override the letter and use the number for data + /// + public int ColumnNumber { get; set; } + + public InformedColumn() : base() + { + + } + + public InformedColumn(UninformedImportColumn column1, int column2) + { + } + } +} diff --git a/ExcelExtensions/Models/Style.cs b/ExcelExtensions/Models/Export/Style.cs similarity index 96% rename from ExcelExtensions/Models/Style.cs rename to ExcelExtensions/Models/Export/Style.cs index 367d038..1809b70 100644 --- a/ExcelExtensions/Models/Style.cs +++ b/ExcelExtensions/Models/Export/Style.cs @@ -3,7 +3,7 @@ using OfficeOpenXml.Style; using System.Drawing; -namespace ExcelExtensions.Models +namespace ExcelExtensions.Models.Export { public class Style { diff --git a/ExcelExtensions/Models/ImportException.cs b/ExcelExtensions/Models/Import/ImportException.cs similarity index 97% rename from ExcelExtensions/Models/ImportException.cs rename to ExcelExtensions/Models/Import/ImportException.cs index 06880cf..c214e84 100644 --- a/ExcelExtensions/Models/ImportException.cs +++ b/ExcelExtensions/Models/Import/ImportException.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; using System.Linq; -namespace ExcelExtensions.Models +namespace ExcelExtensions.Models.Import { /// /// Represents an exception when using the parse functions of excel extensions diff --git a/ExcelExtensions/Models/ParseException.cs b/ExcelExtensions/Models/Import/ParseException.cs similarity index 100% rename from ExcelExtensions/Models/ParseException.cs rename to ExcelExtensions/Models/Import/ParseException.cs diff --git a/ExcelExtensions/Models/ParsedTable.cs b/ExcelExtensions/Models/Import/ParsedTable.cs similarity index 100% rename from ExcelExtensions/Models/ParsedTable.cs rename to ExcelExtensions/Models/Import/ParsedTable.cs diff --git a/ExcelExtensions/Models/LazyColumn.cs b/ExcelExtensions/Models/LazyColumn.cs deleted file mode 100644 index c8d37cc..0000000 --- a/ExcelExtensions/Models/LazyColumn.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Dominic Schira . All Rights Reserved. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace ExcelExtensions.Models -{ - /// - /// Eazy button class - /// - public class LazyColumn : UninformedImportColumn - { - /// - /// same as in as out - /// - public int ColumnLocation { get; set; } - - public LazyColumn() - { - - } - } -} diff --git a/ExcelExtensions/Models/UninformedImportColumn.cs b/ExcelExtensions/Models/UninformedImportColumn.cs deleted file mode 100644 index 0682811..0000000 --- a/ExcelExtensions/Models/UninformedImportColumn.cs +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) Dominic Schira . All Rights Reserved. - -using ExcelExtensions.Interfaces; -using System; -using System.Collections.Generic; -using System.Linq; -using static ExcelExtensions.Enums.Enums; - -namespace ExcelExtensions.Models -{ - public class ImportColumn : ColumnWithSeverity - { - public bool IsRequired { get; set; } - - public ImportColumn() : base() - { - IsRequired = MissingSeverity == ParseExceptionSeverity.Error; - } - - public ImportColumn(Column column, bool required) : base(column, required ? ParseExceptionSeverity.Error : ParseExceptionSeverity.Warning) - { - - } - public ImportColumn(string modelPropertyName, string displayName, FormatType format, bool required = true, int? decimalPrecision = null) : - base(modelPropertyName, displayName, format, required ? ParseExceptionSeverity.Error : ParseExceptionSeverity.Warning, decimalPrecision) - { - - } - } - /// - /// SCAN AND PARSE - /// - public class UninformedImportColumn : ImportColumn - { - /// - /// Represent the list of options for the header name - /// Used for parseing - /// - public List DisplayNameOptions { get; set; } - public UninformedImportColumn() - { - - } - - - /// - /// Adds the header name/title from the column - /// - /// - /// - /// Optional names to search for - public UninformedImportColumn(Column column, bool required, List columnOptions = null) : base(column, required) - { - DisplayNameOptions = columnOptions ?? new List(); - DisplayNameOptions.Add(column.DisplayName); - MissingSeverity = required ? ParseExceptionSeverity.Error : ParseExceptionSeverity.Warning; - } - } - - /// - /// JUST PARSE - /// - public class InformedImportColumn : ImportColumn - { - /// - /// used as a pointer for where we are importing and saved if we are looking for a column that doesn't have a letter - /// This will override the letter and use the number for data - /// - public int ImportColumnNumber { get; set; } - - public InformedImportColumn() : base() - { - - } - - public InformedImportColumn(UninformedImportColumn column1, int column2) - { - } - } - - -} diff --git a/ExcelExtensions/Providers/Export/Exporter.cs b/ExcelExtensions/Providers/Export/Exporter.cs index 9d1c560..3c3e45f 100644 --- a/ExcelExtensions/Providers/Export/Exporter.cs +++ b/ExcelExtensions/Providers/Export/Exporter.cs @@ -3,6 +3,7 @@ using ExcelExtensions.Interfaces; using ExcelExtensions.Interfaces.Export; using ExcelExtensions.Models; +using ExcelExtensions.Models.Export; using OfficeOpenXml; using System; using System.Collections.Generic; @@ -24,7 +25,7 @@ public Exporter(IExtensions excelProvider) } /// - public void ExportTable(ref ExcelWorksheet sheet, List rows, List columnDefinitions, Style style, int headerRow = 1) + public void ExportTable(ref ExcelWorksheet sheet, List rows, List columnDefinitions, Style style, int headerRow = 1) { ExportColumns(ref sheet, rows, columnDefinitions, headerRow); @@ -32,11 +33,11 @@ public void ExportTable(ref ExcelWorksheet sheet, List rows, List } /// - public void ExportColumns(ref ExcelWorksheet sheet, List rows, List columns, int headerRow = 1, string displayNameAdditionalText = null) + public void ExportColumns(ref ExcelWorksheet sheet, List rows, List columns, int headerRow = 1, string displayNameAdditionalText = null) { Type exportModelType = rows.GetType().GetGenericArguments().Single(); - foreach (Column column in columns) + foreach (ExportColumn column in columns) { int rowNumber = headerRow; rowNumber = SetTableHeaderRowNumber(sheet, displayNameAdditionalText, column, rowNumber); @@ -49,7 +50,7 @@ public void ExportColumns(ref ExcelWorksheet sheet, List rows, List(ref ExcelWorksheet sheet, List rows, List /// /// - private int SetTableHeaderRowNumber(ExcelWorksheet sheet, string displayNameAdditionalText, Column column, int row) + private int SetTableHeaderRowNumber(ExcelWorksheet sheet, string displayNameAdditionalText, ExportColumn column, int row) { if (string.IsNullOrEmpty(displayNameAdditionalText)) { - sheet.Cells[row++, column.ExportColumnNumber].Value = column.DisplayName; + sheet.Cells[row++, column.ColumnNumber].Value = column.DisplayName; } else { - sheet.Cells[row++, column.ExportColumnNumber].Value = $"{column.DisplayName} {displayNameAdditionalText}"; ; + sheet.Cells[row++, column.ColumnNumber].Value = $"{column.DisplayName} {displayNameAdditionalText}"; ; } return row; } /// - public void FormatColumn(Column column, ref ExcelWorksheet sheet) + public void FormatColumn(ExportColumn column, ref ExcelWorksheet sheet) { - FormatColumn(ref sheet, column.ExportColumnNumber, column.Format, column.DecimalPrecision); + FormatColumn(ref sheet, column.ColumnNumber, column.Format, column.DecimalPrecision); } public void FormatColumn(ref ExcelWorksheet sheet, string columnLetter, FormatType formatter, int? decimalPrecision = null) @@ -206,7 +207,7 @@ public void FormatColumnRange(ExcelWorksheet itemcodeSheet, int startColumn, int } /// - public void StyleTableHeaderRow(List columns, ref ExcelWorksheet sheet, Style style, int? startrow = null) + public void StyleTableHeaderRow(List columns, ref ExcelWorksheet sheet, Style style, int? startrow = null) { int maxColumn = _excelProvider.FindMaxColumn(columns); int row = startrow ?? 1; diff --git a/ExcelExtensions/Providers/Extensions.cs b/ExcelExtensions/Providers/Extensions.cs index d8a9068..11a8393 100644 --- a/ExcelExtensions/Providers/Extensions.cs +++ b/ExcelExtensions/Providers/Extensions.cs @@ -3,6 +3,7 @@ using ExcelExtensions.Globals; using ExcelExtensions.Interfaces; using ExcelExtensions.Models; +using ExcelExtensions.Models.Columns.Import; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; @@ -198,7 +199,7 @@ public int FindMaxRow(List cells) /// public int FindMaxColumn(List columns) //TODO - => columns.Select(column => column.ExportColumnNumber).Max(); + => columns.Select(column => column.ColumnNumber).Max(); /// public string AddDecimalPlacesToFormat(Column column, string noDecimals) diff --git a/ExcelExtensions/Providers/Import/FileAndSheetValidatior.cs b/ExcelExtensions/Providers/Import/FileAndSheetValidatior.cs index de36605..d88496a 100644 --- a/ExcelExtensions/Providers/Import/FileAndSheetValidatior.cs +++ b/ExcelExtensions/Providers/Import/FileAndSheetValidatior.cs @@ -2,6 +2,7 @@ using ExcelExtensions.Interfaces.Import; using ExcelExtensions.Models; +using ExcelExtensions.Models.Import; using OfficeOpenXml; using System; using System.Collections.Generic; diff --git a/ExcelExtensions/Providers/Import/ImportMapFactory.cs b/ExcelExtensions/Providers/Import/ImportMapFactory.cs index f6e95c2..228eba1 100644 --- a/ExcelExtensions/Providers/Import/ImportMapFactory.cs +++ b/ExcelExtensions/Providers/Import/ImportMapFactory.cs @@ -57,10 +57,10 @@ public List MapObjectToImportColumns(Type modelType, For bool required = attribute?.IsRequired ?? true; // List importKeys = attribute?.ImportColumnTitleOptions ?? new List() { modelPropertyName, textTitle }; - excelColumnDefinitionArray.Add(new InformedImportColumn() + excelColumnDefinitionArray.Add(new InformedColumn() { //If already know our column letter lets use that. - ImportColumnNumber = attribute?.ExportColumnLetter == null ? 0 : _excelExtensions.GetColumnNumber(attribute.ExportColumnLetter), + ColumnNumber = attribute?.ExportColumnLetter == null ? 0 : _excelExtensions.GetColumnNumber(attribute.ExportColumnLetter), Column = new Column(modelPropertyName, textTitle, letter, diff --git a/ExcelExtensions/Providers/Import/Parse/TableParser.cs b/ExcelExtensions/Providers/Import/Parse/TableParser.cs index 2afd268..da66637 100644 --- a/ExcelExtensions/Providers/Import/Parse/TableParser.cs +++ b/ExcelExtensions/Providers/Import/Parse/TableParser.cs @@ -9,6 +9,7 @@ using System.Reflection; using static ExcelExtensions.Enums.Enums; using ExcelExtensions.Interfaces; +using ExcelExtensions.Models.Columns; namespace ExcelExtensions.Providers.Import.Parse { @@ -42,7 +43,7 @@ public ParsedTable UninformedParseTable(List columns, int rowScanCount = 0; //Check for each of the expected columns in - List columnsWithCellAddresses = ScanForHeaderRow(columns, ref workSheet, ref headerRowNumber, maxScanHeaderRowThreashold, ref rowScanCount); + List columnsWithCellAddresses = ScanForHeaderRow(columns, ref workSheet, ref headerRowNumber, maxScanHeaderRowThreashold, ref rowScanCount); if (CheckMissingScannedColumns(headerRowNumber, maxScanHeaderRowThreashold, rowScanCount, columns)) { @@ -53,22 +54,22 @@ public ParsedTable UninformedParseTable(List columns, return ParseRows(columnsWithCellAddresses, workSheet, headerRowNumber); } - public ParsedTable InformedParseTable(List columns, ExcelWorksheet workSheet, int headerRowNumber = 1) + public ParsedTable InformedParseTable(List columns, ExcelWorksheet workSheet, int headerRowNumber = 1) { if (_excelExtensions is null) { throw new ArgumentNullException(nameof(IExtensions), $"Make sure when TableParser is constructed that {nameof(IExtensions)} gets passed in."); } - if (columns.Any(x => x.IsRequired && x.ImportColumnNumber <= 0)) + if (columns.Any(x => x.IsRequired && x.ColumnNumber <= 0)) { throw new ArgumentOutOfRangeException(nameof(columns), "All ColumnTemplate's must have a ColumnNumber. If the ColumnNumber is unknown use the ScanForColumnsAndParseTable method."); } //Assign required columns - foreach (InformedImportColumn col in columns.Where(x => x.IsRequired)) + foreach (InformedColumn col in columns.Where(x => x.IsRequired)) { //TODO this might need changed... - _requiredFieldsColumnLocations.Add(_excelExtensions.GetColumnLetter(col.ImportColumnNumber)); + _requiredFieldsColumnLocations.Add(_excelExtensions.GetColumnLetter(col.ColumnNumber)); } //Parse each row @@ -82,7 +83,7 @@ public ParsedTable InformedParseTable(List columns, Exc /// /// /// - private ParsedTable ParseRows(List columnsWithCellAddresses, ExcelWorksheet workSheet, int headerRowId) + private ParsedTable ParseRows(List columnsWithCellAddresses, ExcelWorksheet workSheet, int headerRowId) { for (int rowNumber = headerRowId + 1; rowNumber <= workSheet.Dimension.End.Row; rowNumber++) { @@ -90,15 +91,15 @@ private ParsedTable ParseRows(List columnsWithCellAddre _singleRowErrors.Clear(); _model = Activator.CreateInstance(); - foreach (InformedImportColumn coltemplate in columnsWithCellAddresses) + foreach (InformedColumn coltemplate in columnsWithCellAddresses) { //If its at defualt(0) or we have reached the end of the sheet bail out - if (coltemplate.ImportColumnNumber < 1 || coltemplate.ImportColumnNumber > workSheet.Dimension.End.Column) + if (coltemplate.ColumnNumber < 1 || coltemplate.ColumnNumber > workSheet.Dimension.End.Column) { continue; } - ExcelRange cell = workSheet.Cells[rowNumber, coltemplate.ImportColumnNumber]; + ExcelRange cell = workSheet.Cells[rowNumber, coltemplate.ColumnNumber]; ParseCell(workSheet, rowNumber, coltemplate, cell); } @@ -146,9 +147,9 @@ private ParsedTable ParseRows(List columnsWithCellAddre /// /// /// There must be at least one required field. - private List ScanForHeaderRow(List columns, ref ExcelWorksheet workSheet, ref int headerRowNumber, int maxScanHeaderRowThreashold, ref int rowScanCount) + private List ScanForHeaderRow(List columns, ref ExcelWorksheet workSheet, ref int headerRowNumber, int maxScanHeaderRowThreashold, ref int rowScanCount) { - List informedColumns = new(); + List informedColumns = new(); do { //Make sure the errors are clear first @@ -237,19 +238,19 @@ private bool CheckMissingScannedColumns(int headerRowId, int maxScanHeaderRowThr /// /// /// - private List FindColumnNamesAndCheckRequiredColumns(List columns, ref ExcelWorksheet workSheet, ref int headerRowId) + private List FindColumnNamesAndCheckRequiredColumns(List columns, ref ExcelWorksheet workSheet, ref int headerRowId) { - List informedColumns = new(); + List informedColumns = new(); foreach (UninformedImportColumn column in columns) { - InformedImportColumn informedImportColumn = null; + InformedColumn informedImportColumn = null; foreach (ExcelRangeBase firstRowCell in workSheet.Cells[headerRowId, workSheet.Dimension.Start.Column, headerRowId, workSheet.Dimension.End.Column]) { if (column.DisplayNameOptions.Any(x => x.Equals(firstRowCell.Text, StringComparison.OrdinalIgnoreCase))) { - informedImportColumn = new InformedImportColumn(column, firstRowCell.Start.Column); + informedImportColumn = new InformedColumn(column, firstRowCell.Start.Column); informedColumns.Add(informedImportColumn); continue; } @@ -280,7 +281,7 @@ private List FindColumnNamesAndCheckRequiredColumns(List. All Rights Reserved. -using ExcelExtensions.Models; +using ExcelExtensions.Models.Import; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; diff --git a/WebApplication/Providers/SampleProvider.cs b/WebApplication/Providers/SampleProvider.cs index aa854bb..f79f84b 100644 --- a/WebApplication/Providers/SampleProvider.cs +++ b/WebApplication/Providers/SampleProvider.cs @@ -15,6 +15,8 @@ using ExcelExtensions.Interfaces; using ExcelExtensions.Interfaces.Export; using System.Drawing; +using ExcelExtensions.Models.Import; +using ExcelExtensions.Models.Export; namespace WebApplication.Providers { From 8277af599de6ceed85a4d42b34811202c55cb668 Mon Sep 17 00:00:00 2001 From: Dom Schira Date: Mon, 21 Jun 2021 18:41:50 -0700 Subject: [PATCH 05/12] Maybe fixing this shitty inheritance --- .../Interfaces/Import/Parse/ITableParser.cs | 2 +- ExcelExtensions/Models/Columns/Column.cs | 17 +----- .../Models/Columns/Export/ExportColumn.cs | 4 +- .../Models/Columns/Import/ImportColumn.cs | 1 - .../InformedImportColumn.cs} | 14 ++--- .../Columns/Import/UninformedImportColumn.cs | 19 ++++-- .../Models/Columns/InAndOutColumn.cs | 25 ++++++++ .../Models/Import/ParseException.cs | 2 +- .../Providers/Import/ImportMapFactory.cs | 59 +++++++++++++++---- .../Providers/Import/Parse/TableParser.cs | 26 ++++---- 10 files changed, 113 insertions(+), 56 deletions(-) rename ExcelExtensions/Models/Columns/{InformedColumn.cs => Import/InformedImportColumn.cs} (64%) create mode 100644 ExcelExtensions/Models/Columns/InAndOutColumn.cs diff --git a/ExcelExtensions/Interfaces/Import/Parse/ITableParser.cs b/ExcelExtensions/Interfaces/Import/Parse/ITableParser.cs index 6000b64..8b88956 100644 --- a/ExcelExtensions/Interfaces/Import/Parse/ITableParser.cs +++ b/ExcelExtensions/Interfaces/Import/Parse/ITableParser.cs @@ -14,6 +14,6 @@ namespace ExcelExtensions.Interfaces.Import.Parse public interface ITableParser { ParsedTable UninformedParseTable(List columns, ExcelWorksheet workSheet, int headerRowNumber = 1, int maxScanHeaderRowThreashold = 100); - ParsedTable InformedParseTable(List columns, ExcelWorksheet workSheet, int headerRowNumber = 1); + ParsedTable InformedParseTable(List columns, ExcelWorksheet workSheet, int headerRowNumber = 1); } } diff --git a/ExcelExtensions/Models/Columns/Column.cs b/ExcelExtensions/Models/Columns/Column.cs index 1ed0b2f..af97712 100644 --- a/ExcelExtensions/Models/Columns/Column.cs +++ b/ExcelExtensions/Models/Columns/Column.cs @@ -11,12 +11,6 @@ namespace ExcelExtensions.Models /// public class Column { - private IExtensions excelExtensions; - private Type objType; - private string v1; - private FormatType @string; - private int v2; - public string ModelProperty { get; set; } /// /// Represents the human readable column header name/title @@ -31,6 +25,8 @@ public class Column /// public int? DecimalPrecision { get; set; } + //public int? ColumnNumber { get; set; } + public Column() { @@ -42,14 +38,5 @@ public Column(string modelPropertyName, string displayName, FormatType format, i Format = format; DecimalPrecision = decimalPrecision; } - - public Column(IExtensions excelExtensions, Type objType, string v1, FormatType @string, int v2) - { - this.excelExtensions = excelExtensions; - this.objType = objType; - this.v1 = v1; - this.@string = @string; - this.v2 = v2; - } } } diff --git a/ExcelExtensions/Models/Columns/Export/ExportColumn.cs b/ExcelExtensions/Models/Columns/Export/ExportColumn.cs index 5424347..4e607cf 100644 --- a/ExcelExtensions/Models/Columns/Export/ExportColumn.cs +++ b/ExcelExtensions/Models/Columns/Export/ExportColumn.cs @@ -1,15 +1,15 @@ // Copyright (c) Dominic Schira . All Rights Reserved. using ExcelExtensions.Interfaces; -using ExcelExtensions.Models.Columns; namespace ExcelExtensions.Models { /// /// Represents an excel column /// - public class ExportColumn : InformedColumn + public class ExportColumn : Column { + public int ColumnNumber { get; set; } /// /// Represents the location/letter of the excel column. Ex "C" /// Used for exports and import where we know where to look and are not parsing for new col locations diff --git a/ExcelExtensions/Models/Columns/Import/ImportColumn.cs b/ExcelExtensions/Models/Columns/Import/ImportColumn.cs index 4493dd1..c9fd80d 100644 --- a/ExcelExtensions/Models/Columns/Import/ImportColumn.cs +++ b/ExcelExtensions/Models/Columns/Import/ImportColumn.cs @@ -17,7 +17,6 @@ public ImportColumn() : base() { IsRequired = MissingSeverity == ParseExceptionSeverity.Error; } - public ImportColumn(Column column, bool required) : base(column, required ? ParseExceptionSeverity.Error : ParseExceptionSeverity.Warning) { diff --git a/ExcelExtensions/Models/Columns/InformedColumn.cs b/ExcelExtensions/Models/Columns/Import/InformedImportColumn.cs similarity index 64% rename from ExcelExtensions/Models/Columns/InformedColumn.cs rename to ExcelExtensions/Models/Columns/Import/InformedImportColumn.cs index 11662ff..c2df831 100644 --- a/ExcelExtensions/Models/Columns/InformedColumn.cs +++ b/ExcelExtensions/Models/Columns/Import/InformedImportColumn.cs @@ -1,18 +1,13 @@ // Copyright (c) Dominic Schira . All Rights Reserved. using ExcelExtensions.Models.Columns.Import; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace ExcelExtensions.Models.Columns { /// - /// JUST PARSE + /// Works for parse and export /// - public class InformedColumn : ColumnWithSeverity + public class InformedImportColumn : ImportColumn { /// /// used as a pointer for where we are importing and saved if we are looking for a column that doesn't have a letter @@ -20,13 +15,14 @@ public class InformedColumn : ColumnWithSeverity /// public int ColumnNumber { get; set; } - public InformedColumn() : base() + public InformedImportColumn() : base() { } - public InformedColumn(UninformedImportColumn column1, int column2) + public InformedImportColumn(UninformedImportColumn column, int columnNumber) : base(column, column.IsRequired) { + ColumnNumber = columnNumber; } } } diff --git a/ExcelExtensions/Models/Columns/Import/UninformedImportColumn.cs b/ExcelExtensions/Models/Columns/Import/UninformedImportColumn.cs index ee2ec6e..6a6294a 100644 --- a/ExcelExtensions/Models/Columns/Import/UninformedImportColumn.cs +++ b/ExcelExtensions/Models/Columns/Import/UninformedImportColumn.cs @@ -25,6 +25,20 @@ public UninformedImportColumn() } + /// + /// If not options we will add the display name + /// + /// + /// + /// + /// + /// + /// + public UninformedImportColumn(string modelPropertyName, string displayName, FormatType format, bool required = true, List columnOptions = null, int? decimalPrecision = null) : base(modelPropertyName, displayName, format, required, decimalPrecision) + { + DisplayNameOptions = columnOptions ?? new List() { displayName }; + MissingSeverity = required ? ParseExceptionSeverity.Error : ParseExceptionSeverity.Warning; + } /// /// Adds the header name/title from the column @@ -32,11 +46,8 @@ public UninformedImportColumn() /// /// /// Optional names to search for - public UninformedImportColumn(Column column, bool required, List columnOptions = null) : base(column, required) + public UninformedImportColumn(Column column, bool required, List columnOptions = null) : this(column.ModelProperty, column.DisplayName, column.Format, required, columnOptions, column.DecimalPrecision) { - DisplayNameOptions = columnOptions ?? new List(); - DisplayNameOptions.Add(column.DisplayName); - MissingSeverity = required ? ParseExceptionSeverity.Error : ParseExceptionSeverity.Warning; } } diff --git a/ExcelExtensions/Models/Columns/InAndOutColumn.cs b/ExcelExtensions/Models/Columns/InAndOutColumn.cs new file mode 100644 index 0000000..c765c7e --- /dev/null +++ b/ExcelExtensions/Models/Columns/InAndOutColumn.cs @@ -0,0 +1,25 @@ +// Copyright (c) Dominic Schira . All Rights Reserved. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ExcelExtensions.Models.Columns +{ + public class InAndOutColumn : UninformedImportColumn + { + public int ColumnNumber { get; set; } + + public InAndOutColumn() : base() + { + + } + + public InAndOutColumn() + { + + } + } +} diff --git a/ExcelExtensions/Models/Import/ParseException.cs b/ExcelExtensions/Models/Import/ParseException.cs index 064fe48..86995e2 100644 --- a/ExcelExtensions/Models/Import/ParseException.cs +++ b/ExcelExtensions/Models/Import/ParseException.cs @@ -1,6 +1,7 @@ // Copyright (c) Dominic Schira . All Rights Reserved. using ExcelExtensions.Globals; +using ExcelExtensions.Models.Columns.Import; using static ExcelExtensions.Enums.Enums; namespace ExcelExtensions.Models @@ -69,7 +70,6 @@ public ParseException(string sheetName) public ParseException(string sheetName, ImportColumn column) : this (sheetName) { ColumnHeader = column.ModelProperty; - //ColumnHeader = column.ColumnHeader; //todo FormatType = column.Format; Severity = column.MissingSeverity; } diff --git a/ExcelExtensions/Providers/Import/ImportMapFactory.cs b/ExcelExtensions/Providers/Import/ImportMapFactory.cs index 228eba1..ed82126 100644 --- a/ExcelExtensions/Providers/Import/ImportMapFactory.cs +++ b/ExcelExtensions/Providers/Import/ImportMapFactory.cs @@ -2,6 +2,7 @@ using ExcelExtensions.Interfaces; using ExcelExtensions.Models; +using ExcelExtensions.Models.Columns; using System; using System.Collections.Generic; using System.Linq; @@ -22,25 +23,28 @@ public ImportMapFactory(IExtensions excelExtensions) } + //If you give me an int you know where it is, or if you give me a letter you know where it is - public List MapObjectToImportColumns(Type modelType, FormatType formatType = FormatType.String, int startColumnNumber = 1) - { - //If you give me an int you know where it is, or if you give me a letter you know where it is + //make methods - //make methods + //1st sets up just for imports in case you need to make tweaks (would have to know the letters or numbers) - //1st sets up just for imports in case you need to make tweaks (would have to know the letters or numbers) + //2nd set up just for exports (would have to know the letters or numbers) - //2nd set up just for exports (would have to know the letters or numbers) + //3rd, option where you really don't care where you export data because it is in order how you set up your model - //3rd, option where you really don't care where you export data because it is in order how you set up your model + //Could possible make Column and protected class and make ImportColumn and ExportColum then a class that encapsulates both for a LazyColumn - //Could possible make Column and protected class and make ImportColumn and ExportColum then a class that encapsulates both for a LazyColumn + public List GetExportColumns(Type modelType, FormatType formatType = FormatType.String, int startColumnNumber = 1) + { + } + public List GetInformedImportColumns(Type modelType, FormatType formatType = FormatType.String, int startColumnNumber = 1) + { int currentColumnNumber = startColumnNumber; - List excelColumnDefinitionArray = new(); + List excelColumnDefinitionArray = new(); foreach (PropertyInfo item in modelType.GetProperties()) { @@ -57,7 +61,7 @@ public List MapObjectToImportColumns(Type modelType, For bool required = attribute?.IsRequired ?? true; // List importKeys = attribute?.ImportColumnTitleOptions ?? new List() { modelPropertyName, textTitle }; - excelColumnDefinitionArray.Add(new InformedColumn() + excelColumnDefinitionArray.Add(new InformedImportColumn() { //If already know our column letter lets use that. ColumnNumber = attribute?.ExportColumnLetter == null ? 0 : _excelExtensions.GetColumnNumber(attribute.ExportColumnLetter), @@ -73,6 +77,41 @@ public List MapObjectToImportColumns(Type modelType, For currentColumnNumber++; } + return excelColumnDefinitionArray; + } + public List GetUninformedImportColumns(Type modelType, FormatType formatType = FormatType.String, int startColumnNumber = 1) + { + int currentColumnNumber = startColumnNumber; + List excelColumnDefinitionArray = new(); + + foreach (PropertyInfo item in modelType.GetProperties()) + { + //read the display name attirube + string modelPropertyName = _excelExtensions.GetExportModelPropertyNameAndDisplayName(modelType, item.Name, out string textTitle); + + ExcelExtensionsColumnAttribute attribute = item.GetCustomAttribute(); + + //Give the default format if not avail be + FormatType format = attribute?.Format ?? formatType; + + //TODO: theses all below need to be re though with a new idea of separating the column types out + string letter = attribute?.ExportColumnLetter ?? _excelExtensions.GetColumnLetter(currentColumnNumber); + + bool required = attribute?.IsRequired ?? true; // + List importKeys = attribute?.ImportColumnTitleOptions ?? new List() { modelPropertyName, textTitle }; + + excelColumnDefinitionArray.Add(new UninformedImportColumn(modelPropertyName, + textTitle, + format, + required, + importKeys, + attribute?.DecimalPrecision) + ); + + //next column + currentColumnNumber++; + } + return excelColumnDefinitionArray; } } diff --git a/ExcelExtensions/Providers/Import/Parse/TableParser.cs b/ExcelExtensions/Providers/Import/Parse/TableParser.cs index da66637..f4c453a 100644 --- a/ExcelExtensions/Providers/Import/Parse/TableParser.cs +++ b/ExcelExtensions/Providers/Import/Parse/TableParser.cs @@ -10,6 +10,7 @@ using static ExcelExtensions.Enums.Enums; using ExcelExtensions.Interfaces; using ExcelExtensions.Models.Columns; +using ExcelExtensions.Models.Columns.Import; namespace ExcelExtensions.Providers.Import.Parse { @@ -43,7 +44,7 @@ public ParsedTable UninformedParseTable(List columns, int rowScanCount = 0; //Check for each of the expected columns in - List columnsWithCellAddresses = ScanForHeaderRow(columns, ref workSheet, ref headerRowNumber, maxScanHeaderRowThreashold, ref rowScanCount); + List columnsWithCellAddresses = ScanForHeaderRow(columns, ref workSheet, ref headerRowNumber, maxScanHeaderRowThreashold, ref rowScanCount); if (CheckMissingScannedColumns(headerRowNumber, maxScanHeaderRowThreashold, rowScanCount, columns)) { @@ -54,7 +55,7 @@ public ParsedTable UninformedParseTable(List columns, return ParseRows(columnsWithCellAddresses, workSheet, headerRowNumber); } - public ParsedTable InformedParseTable(List columns, ExcelWorksheet workSheet, int headerRowNumber = 1) + public ParsedTable InformedParseTable(List columns, ExcelWorksheet workSheet, int headerRowNumber = 1) { if (_excelExtensions is null) { @@ -66,9 +67,8 @@ public ParsedTable InformedParseTable(List columns, ExcelWork throw new ArgumentOutOfRangeException(nameof(columns), "All ColumnTemplate's must have a ColumnNumber. If the ColumnNumber is unknown use the ScanForColumnsAndParseTable method."); } //Assign required columns - foreach (InformedColumn col in columns.Where(x => x.IsRequired)) - { - //TODO this might need changed... + foreach (InformedImportColumn col in columns.Where(x => x.IsRequired)) + { _requiredFieldsColumnLocations.Add(_excelExtensions.GetColumnLetter(col.ColumnNumber)); } @@ -83,7 +83,7 @@ public ParsedTable InformedParseTable(List columns, ExcelWork /// /// /// - private ParsedTable ParseRows(List columnsWithCellAddresses, ExcelWorksheet workSheet, int headerRowId) + private ParsedTable ParseRows(List columnsWithCellAddresses, ExcelWorksheet workSheet, int headerRowId) { for (int rowNumber = headerRowId + 1; rowNumber <= workSheet.Dimension.End.Row; rowNumber++) { @@ -91,7 +91,7 @@ private ParsedTable ParseRows(List columnsWithCellAddresses, _singleRowErrors.Clear(); _model = Activator.CreateInstance(); - foreach (InformedColumn coltemplate in columnsWithCellAddresses) + foreach (InformedImportColumn coltemplate in columnsWithCellAddresses) { //If its at defualt(0) or we have reached the end of the sheet bail out if (coltemplate.ColumnNumber < 1 || coltemplate.ColumnNumber > workSheet.Dimension.End.Column) @@ -147,9 +147,9 @@ private ParsedTable ParseRows(List columnsWithCellAddresses, /// /// /// There must be at least one required field. - private List ScanForHeaderRow(List columns, ref ExcelWorksheet workSheet, ref int headerRowNumber, int maxScanHeaderRowThreashold, ref int rowScanCount) + private List ScanForHeaderRow(List columns, ref ExcelWorksheet workSheet, ref int headerRowNumber, int maxScanHeaderRowThreashold, ref int rowScanCount) { - List informedColumns = new(); + List informedColumns = new(); do { //Make sure the errors are clear first @@ -238,19 +238,19 @@ private bool CheckMissingScannedColumns(int headerRowId, int maxScanHeaderRowThr /// /// /// - private List FindColumnNamesAndCheckRequiredColumns(List columns, ref ExcelWorksheet workSheet, ref int headerRowId) + private List FindColumnNamesAndCheckRequiredColumns(List columns, ref ExcelWorksheet workSheet, ref int headerRowId) { - List informedColumns = new(); + List informedColumns = new(); foreach (UninformedImportColumn column in columns) { - InformedColumn informedImportColumn = null; + InformedImportColumn informedImportColumn = null; foreach (ExcelRangeBase firstRowCell in workSheet.Cells[headerRowId, workSheet.Dimension.Start.Column, headerRowId, workSheet.Dimension.End.Column]) { if (column.DisplayNameOptions.Any(x => x.Equals(firstRowCell.Text, StringComparison.OrdinalIgnoreCase))) { - informedImportColumn = new InformedColumn(column, firstRowCell.Start.Column); + informedImportColumn = new InformedImportColumn(column, firstRowCell.Start.Column); informedColumns.Add(informedImportColumn); continue; } From 16fe83126d7616c451f5118e4e8a7af7fd5671d2 Mon Sep 17 00:00:00 2001 From: Dom Schira Date: Mon, 21 Jun 2021 19:14:01 -0700 Subject: [PATCH 06/12] Things are making sense --- .../Interfaces/Export/IExporter.cs | 8 +- ExcelExtensions/Interfaces/IExtensions.cs | 4 +- .../Interfaces/Import/Parse/ITableParser.cs | 1 + ExcelExtensions/Models/Columns/Column.cs | 2 +- .../Models/Columns/Export/ExportColumn.cs | 1 - .../Columns/Import/InformedImportColumn.cs | 2 +- .../Models/Columns/InAndOutColumn.cs | 19 ++-- ExcelExtensions/Providers/Export/Exporter.cs | 29 ++++-- ExcelExtensions/Providers/Extensions.cs | 2 +- .../Providers/Import/ImportMapFactory.cs | 97 +++++++++++-------- .../Providers/Import/Parse/TableParser.cs | 4 +- 11 files changed, 100 insertions(+), 69 deletions(-) diff --git a/ExcelExtensions/Interfaces/Export/IExporter.cs b/ExcelExtensions/Interfaces/Export/IExporter.cs index 0e7423b..00fb377 100644 --- a/ExcelExtensions/Interfaces/Export/IExporter.cs +++ b/ExcelExtensions/Interfaces/Export/IExporter.cs @@ -24,7 +24,7 @@ public interface IExporter /// /// /// - void ExportTable(ref ExcelWorksheet sheet, List rows, List columnDefinitions, Style style, int headerRow = 1); + void ExportTable(ref ExcelWorksheet sheet, List rows, List columnDefinitions, Style style, int headerRow = 1); /// /// Export list of columns to an /// @@ -34,13 +34,13 @@ public interface IExporter /// /// /// - void ExportColumns(ref ExcelWorksheet sheet, List rows, List columns, int headerRow = 1, string displayNameAdditionalText = null); + void ExportColumns(ref ExcelWorksheet sheet, List rows, List columns, int headerRow = 1, string displayNameAdditionalText = null); /// /// Format the column of an /// /// /// - void FormatColumn(ExportColumn column, ref ExcelWorksheet sheet); + void FormatColumn(Column column, ref ExcelWorksheet sheet); /// /// Format the column of an /// @@ -67,6 +67,6 @@ public interface IExporter /// /// /// - void StyleTableHeaderRow(List columns, ref ExcelWorksheet sheet, Style style, int? startrow = null); + void StyleTableHeaderRow(List columns, ref ExcelWorksheet sheet, Style style, int? startrow = null); } } \ No newline at end of file diff --git a/ExcelExtensions/Interfaces/IExtensions.cs b/ExcelExtensions/Interfaces/IExtensions.cs index 474cc9d..80314d7 100644 --- a/ExcelExtensions/Interfaces/IExtensions.cs +++ b/ExcelExtensions/Interfaces/IExtensions.cs @@ -38,7 +38,7 @@ public interface IExtensions /// /// list of ExcelColumnDefinitions /// The max column in the list cells, represented as an - int FindMaxColumn(List columns); + int FindMaxColumn(List columns); /// /// Provides the max row used in a cell sheet based upon Cells. /// @@ -108,7 +108,7 @@ public interface IExtensions KeyValuePair LogDeveloperException(string worksheetName, ImportColumn column, string cellAddress, string message, string modelPropertyName); KeyValuePair LogDeveloperException(string worksheetName, ImportColumn column, string cellAddress, int rowNumber, string message); KeyValuePair LogNullReferenceException(string worksheetName, ImportColumn column, string cellAddress, string modelPropertyName); - KeyValuePair LogNullReferenceException(string worksheetName, ImportColumn column, string cellAddress, int rowNumber); + KeyValuePair LogNullReferenceException(string worksheetName,ImportColumn column, string cellAddress, int rowNumber); KeyValuePair LogCellException(string worksheetName, ImportColumn column, string cellAddress, int rowNumber); KeyValuePair LogCellException(string worksheetName, ImportColumn column, string cellAddress, string modelPropertyName); diff --git a/ExcelExtensions/Interfaces/Import/Parse/ITableParser.cs b/ExcelExtensions/Interfaces/Import/Parse/ITableParser.cs index 8b88956..5fac5fe 100644 --- a/ExcelExtensions/Interfaces/Import/Parse/ITableParser.cs +++ b/ExcelExtensions/Interfaces/Import/Parse/ITableParser.cs @@ -2,6 +2,7 @@ using ExcelExtensions.Models; using ExcelExtensions.Models.Columns; +using ExcelExtensions.Models.Columns.Import; using OfficeOpenXml; using System.Collections.Generic; diff --git a/ExcelExtensions/Models/Columns/Column.cs b/ExcelExtensions/Models/Columns/Column.cs index af97712..0137a24 100644 --- a/ExcelExtensions/Models/Columns/Column.cs +++ b/ExcelExtensions/Models/Columns/Column.cs @@ -25,7 +25,7 @@ public class Column /// public int? DecimalPrecision { get; set; } - //public int? ColumnNumber { get; set; } + public int? ColumnNumber { get; set; } public Column() { diff --git a/ExcelExtensions/Models/Columns/Export/ExportColumn.cs b/ExcelExtensions/Models/Columns/Export/ExportColumn.cs index 4e607cf..46dd891 100644 --- a/ExcelExtensions/Models/Columns/Export/ExportColumn.cs +++ b/ExcelExtensions/Models/Columns/Export/ExportColumn.cs @@ -9,7 +9,6 @@ namespace ExcelExtensions.Models /// public class ExportColumn : Column { - public int ColumnNumber { get; set; } /// /// Represents the location/letter of the excel column. Ex "C" /// Used for exports and import where we know where to look and are not parsing for new col locations diff --git a/ExcelExtensions/Models/Columns/Import/InformedImportColumn.cs b/ExcelExtensions/Models/Columns/Import/InformedImportColumn.cs index c2df831..8af0d0c 100644 --- a/ExcelExtensions/Models/Columns/Import/InformedImportColumn.cs +++ b/ExcelExtensions/Models/Columns/Import/InformedImportColumn.cs @@ -13,7 +13,7 @@ public class InformedImportColumn : ImportColumn /// used as a pointer for where we are importing and saved if we are looking for a column that doesn't have a letter /// This will override the letter and use the number for data /// - public int ColumnNumber { get; set; } + public new int ColumnNumber { get; set; } public InformedImportColumn() : base() { diff --git a/ExcelExtensions/Models/Columns/InAndOutColumn.cs b/ExcelExtensions/Models/Columns/InAndOutColumn.cs index c765c7e..05feb23 100644 --- a/ExcelExtensions/Models/Columns/InAndOutColumn.cs +++ b/ExcelExtensions/Models/Columns/InAndOutColumn.cs @@ -1,25 +1,30 @@ // Copyright (c) Dominic Schira . All Rights Reserved. -using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using static ExcelExtensions.Enums.Enums; namespace ExcelExtensions.Models.Columns { + /// + /// Pre defined export location based on colom order, finds colums based on names provided + /// public class InAndOutColumn : UninformedImportColumn { - public int ColumnNumber { get; set; } + + /// + /// Becasue this will use an uninformed when parsing we will search + /// + public new int ColumnNumber { get; set; } public InAndOutColumn() : base() { } - public InAndOutColumn() + public InAndOutColumn(string modelPropertyName, string displayName, int columnNumber, FormatType format, bool required = true, List columnOptions = null, int? decimalPrecision = null) : + base(modelPropertyName, displayName, format, required, columnOptions, decimalPrecision) { - + ColumnNumber = columnNumber; } } } diff --git a/ExcelExtensions/Providers/Export/Exporter.cs b/ExcelExtensions/Providers/Export/Exporter.cs index 3c3e45f..a7314fe 100644 --- a/ExcelExtensions/Providers/Export/Exporter.cs +++ b/ExcelExtensions/Providers/Export/Exporter.cs @@ -25,7 +25,7 @@ public Exporter(IExtensions excelProvider) } /// - public void ExportTable(ref ExcelWorksheet sheet, List rows, List columnDefinitions, Style style, int headerRow = 1) + public void ExportTable(ref ExcelWorksheet sheet, List rows, List columnDefinitions, Style style, int headerRow = 1) { ExportColumns(ref sheet, rows, columnDefinitions, headerRow); @@ -33,7 +33,7 @@ public void ExportTable(ref ExcelWorksheet sheet, List rows, List - public void ExportColumns(ref ExcelWorksheet sheet, List rows, List columns, int headerRow = 1, string displayNameAdditionalText = null) + public void ExportColumns(ref ExcelWorksheet sheet, List rows, List columns, int headerRow = 1, string displayNameAdditionalText = null) { Type exportModelType = rows.GetType().GetGenericArguments().Single(); @@ -47,10 +47,11 @@ public void ExportColumns(ref ExcelWorksheet sheet, List rows, List(ref ExcelWorksheet sheet, List rows, List /// /// - private int SetTableHeaderRowNumber(ExcelWorksheet sheet, string displayNameAdditionalText, ExportColumn column, int row) + private int SetTableHeaderRowNumber(ExcelWorksheet sheet, string displayNameAdditionalText, Column column, int row) { + CheckForNullColumnNumber(column); if (string.IsNullOrEmpty(displayNameAdditionalText)) { - sheet.Cells[row++, column.ColumnNumber].Value = column.DisplayName; + sheet.Cells[row++, (int)column.ColumnNumber].Value = column.DisplayName; } else { - sheet.Cells[row++, column.ColumnNumber].Value = $"{column.DisplayName} {displayNameAdditionalText}"; ; + sheet.Cells[row++, (int)column.ColumnNumber].Value = $"{column.DisplayName} {displayNameAdditionalText}"; ; } return row; } + private static void CheckForNullColumnNumber(Column column) + { + if (column.ColumnNumber is null) + { + throw new NullReferenceException($"Col number cannot be null for property {column.ModelProperty}"); + } + } + /// - public void FormatColumn(ExportColumn column, ref ExcelWorksheet sheet) + public void FormatColumn(Column column, ref ExcelWorksheet sheet) { - FormatColumn(ref sheet, column.ColumnNumber, column.Format, column.DecimalPrecision); + CheckForNullColumnNumber(column); + FormatColumn(ref sheet, (int)column.ColumnNumber, column.Format, column.DecimalPrecision); } public void FormatColumn(ref ExcelWorksheet sheet, string columnLetter, FormatType formatter, int? decimalPrecision = null) @@ -207,7 +218,7 @@ public void FormatColumnRange(ExcelWorksheet itemcodeSheet, int startColumn, int } /// - public void StyleTableHeaderRow(List columns, ref ExcelWorksheet sheet, Style style, int? startrow = null) + public void StyleTableHeaderRow(List columns, ref ExcelWorksheet sheet, Style style, int? startrow = null) { int maxColumn = _excelProvider.FindMaxColumn(columns); int row = startrow ?? 1; diff --git a/ExcelExtensions/Providers/Extensions.cs b/ExcelExtensions/Providers/Extensions.cs index 11a8393..96e9b45 100644 --- a/ExcelExtensions/Providers/Extensions.cs +++ b/ExcelExtensions/Providers/Extensions.cs @@ -197,7 +197,7 @@ public int FindMaxRow(List cells) /// - public int FindMaxColumn(List columns) + public int FindMaxColumn(List columns) //TODO => columns.Select(column => column.ColumnNumber).Max(); diff --git a/ExcelExtensions/Providers/Import/ImportMapFactory.cs b/ExcelExtensions/Providers/Import/ImportMapFactory.cs index ed82126..4768594 100644 --- a/ExcelExtensions/Providers/Import/ImportMapFactory.cs +++ b/ExcelExtensions/Providers/Import/ImportMapFactory.cs @@ -3,6 +3,7 @@ using ExcelExtensions.Interfaces; using ExcelExtensions.Models; using ExcelExtensions.Models.Columns; +using ExcelExtensions.Models.Columns.Import; using System; using System.Collections.Generic; using System.Linq; @@ -39,7 +40,14 @@ public ImportMapFactory(IExtensions excelExtensions) public List GetExportColumns(Type modelType, FormatType formatType = FormatType.String, int startColumnNumber = 1) { + List excelColumnDefinitionArray = new(); + foreach (PropertyInfo item in modelType.GetProperties()) + { + GetColumnAttributes(modelType, item, formatType, out string modelPropertyName, out string displayName, out ExcelExtensionsColumnAttribute attribute, out FormatType format, out bool required); + + } + return excelColumnDefinitionArray; } public List GetInformedImportColumns(Type modelType, FormatType formatType = FormatType.String, int startColumnNumber = 1) { @@ -48,31 +56,14 @@ public List GetInformedImportColumns(Type modelType, Forma foreach (PropertyInfo item in modelType.GetProperties()) { - //read the display name attirube - string modelPropertyName = _excelExtensions.GetExportModelPropertyNameAndDisplayName(modelType, item.Name, out string textTitle); - - ExcelExtensionsColumnAttribute attribute = item.GetCustomAttribute(); - - //Give the default format if not avail be - FormatType format = attribute?.Format ?? formatType; + GetColumnAttributes(modelType, item, formatType, out string modelPropertyName, out string displayName, out ExcelExtensionsColumnAttribute attribute, out FormatType format, out bool required); //TODO: theses all below need to be re though with a new idea of separating the column types out string letter = attribute?.ExportColumnLetter ?? _excelExtensions.GetColumnLetter(currentColumnNumber); - bool required = attribute?.IsRequired ?? true; // - List importKeys = attribute?.ImportColumnTitleOptions ?? new List() { modelPropertyName, textTitle }; - - excelColumnDefinitionArray.Add(new InformedImportColumn() - { - //If already know our column letter lets use that. - ColumnNumber = attribute?.ExportColumnLetter == null ? 0 : _excelExtensions.GetColumnNumber(attribute.ExportColumnLetter), - Column = new Column(modelPropertyName, - textTitle, - letter, - format, - attribute?.DecimalPrecision), - DisplayNameOptions = importKeys, - IsRequired = required - }); + + List importKeys = attribute?.ImportColumnTitleOptions ?? new List() { modelPropertyName, displayName }; + + //next column currentColumnNumber++; } @@ -81,38 +72,62 @@ public List GetInformedImportColumns(Type modelType, Forma } public List GetUninformedImportColumns(Type modelType, FormatType formatType = FormatType.String, int startColumnNumber = 1) { - int currentColumnNumber = startColumnNumber; List excelColumnDefinitionArray = new(); foreach (PropertyInfo item in modelType.GetProperties()) { - //read the display name attirube - string modelPropertyName = _excelExtensions.GetExportModelPropertyNameAndDisplayName(modelType, item.Name, out string textTitle); + GetColumnAttributes(modelType, item, formatType, out string modelPropertyName, out string displayName, out ExcelExtensionsColumnAttribute attribute, out FormatType format, out bool required); - ExcelExtensionsColumnAttribute attribute = item.GetCustomAttribute(); + - //Give the default format if not avail be - FormatType format = attribute?.Format ?? formatType; + // + List importKeys = attribute?.ImportColumnTitleOptions ?? new List() { modelPropertyName, displayName }; - //TODO: theses all below need to be re though with a new idea of separating the column types out - string letter = attribute?.ExportColumnLetter ?? _excelExtensions.GetColumnLetter(currentColumnNumber); - - bool required = attribute?.IsRequired ?? true; // - List importKeys = attribute?.ImportColumnTitleOptions ?? new List() { modelPropertyName, textTitle }; - - excelColumnDefinitionArray.Add(new UninformedImportColumn(modelPropertyName, - textTitle, + excelColumnDefinitionArray.Add( + new UninformedImportColumn(modelPropertyName, + displayName, format, required, importKeys, - attribute?.DecimalPrecision) - ); - - //next column - currentColumnNumber++; + attribute?.DecimalPrecision)); } return excelColumnDefinitionArray; } + + public List GetInAndOutColumns(Type modelType, FormatType formatType = FormatType.String, int startColumnNumber = 1) + { + List excelColumnDefinitionArray = new(); + int currentColumnNumber = startColumnNumber; + + foreach (PropertyInfo item in modelType.GetProperties()) + { + GetColumnAttributes(modelType, item, formatType, out string modelPropertyName, out string displayName, out ExcelExtensionsColumnAttribute attribute, out FormatType format, out bool required); + + List importKeys = attribute?.ImportColumnTitleOptions ?? new List() { modelPropertyName, displayName }; + + excelColumnDefinitionArray.Add( + new InAndOutColumn(modelPropertyName, + displayName, // + currentColumnNumber++, //export location + format, + required, + importKeys, + attribute?.DecimalPrecision)); + + } + return excelColumnDefinitionArray; + } + + private void GetColumnAttributes(Type modelType, PropertyInfo item, FormatType formatType, out string modelPropertyName, out string displayName, out ExcelExtensionsColumnAttribute attribute, out FormatType format, out bool required) + { + //read the display name attirube + modelPropertyName = _excelExtensions.GetExportModelPropertyNameAndDisplayName(modelType, item.Name, out displayName); + attribute = item.GetCustomAttribute(); + //Give the default format if not avail be + format = attribute?.Format ?? formatType; + required = attribute?.IsRequired ?? true; + } + } } diff --git a/ExcelExtensions/Providers/Import/Parse/TableParser.cs b/ExcelExtensions/Providers/Import/Parse/TableParser.cs index f4c453a..98338b3 100644 --- a/ExcelExtensions/Providers/Import/Parse/TableParser.cs +++ b/ExcelExtensions/Providers/Import/Parse/TableParser.cs @@ -297,7 +297,7 @@ private List FindColumnNamesAndCheckRequiredColumns(List /// /// Will throw errors. disable them when debugging through this dll file. - private void ParseCell(ExcelWorksheet workSheet, int rowNumber, ImportColumn column, ExcelRange cell) + private void ParseCell(ExcelWorksheet workSheet, int rowNumber, InformedImportColumn column, ExcelRange cell) { switch (column.Format) { @@ -559,7 +559,7 @@ private void ParseCell(ExcelWorksheet workSheet, int rowNumber, ImportColumn col /// /// /// - private void SetValue(ExcelWorksheet workSheet, int rowNumber, ImportColumn coltemplate, ExcelRange cell, object value) + private void SetValue(ExcelWorksheet workSheet, int rowNumber, InformedImportColumn coltemplate, ExcelRange cell, object value) { try { From f8f4708064eed204949826a0904fb4f4625712cd Mon Sep 17 00:00:00 2001 From: Dom Schira Date: Mon, 21 Jun 2021 19:42:22 -0700 Subject: [PATCH 07/12] map wrote for column number --- .../Columns/Import/InformedImportColumn.cs | 7 ++ .../Providers/Import/ImportMapFactory.cs | 74 ++++++++++++++----- 2 files changed, 61 insertions(+), 20 deletions(-) diff --git a/ExcelExtensions/Models/Columns/Import/InformedImportColumn.cs b/ExcelExtensions/Models/Columns/Import/InformedImportColumn.cs index 8af0d0c..18166c5 100644 --- a/ExcelExtensions/Models/Columns/Import/InformedImportColumn.cs +++ b/ExcelExtensions/Models/Columns/Import/InformedImportColumn.cs @@ -1,6 +1,7 @@ // Copyright (c) Dominic Schira . All Rights Reserved. using ExcelExtensions.Models.Columns.Import; +using static ExcelExtensions.Enums.Enums; namespace ExcelExtensions.Models.Columns { @@ -24,5 +25,11 @@ public InformedImportColumn(UninformedImportColumn column, int columnNumber) : b { ColumnNumber = columnNumber; } + + public InformedImportColumn(string modelPropertyName, string displayName, int columnNumber, FormatType format, bool required = true, int? decimalPrecision = null) : + base (modelPropertyName, displayName, format, required, decimalPrecision) + { + ColumnNumber = columnNumber; + } } } diff --git a/ExcelExtensions/Providers/Import/ImportMapFactory.cs b/ExcelExtensions/Providers/Import/ImportMapFactory.cs index 4768594..2f9f438 100644 --- a/ExcelExtensions/Providers/Import/ImportMapFactory.cs +++ b/ExcelExtensions/Providers/Import/ImportMapFactory.cs @@ -24,20 +24,8 @@ public ImportMapFactory(IExtensions excelExtensions) } - //If you give me an int you know where it is, or if you give me a letter you know where it is - - //make methods - - //1st sets up just for imports in case you need to make tweaks (would have to know the letters or numbers) - //2nd set up just for exports (would have to know the letters or numbers) - - //3rd, option where you really don't care where you export data because it is in order how you set up your model - - - //Could possible make Column and protected class and make ImportColumn and ExportColum then a class that encapsulates both for a LazyColumn - public List GetExportColumns(Type modelType, FormatType formatType = FormatType.String, int startColumnNumber = 1) { List excelColumnDefinitionArray = new(); @@ -49,20 +37,66 @@ public List GetExportColumns(Type modelType, FormatType formatType } return excelColumnDefinitionArray; } + //1st sets up just for imports in case you need to make tweaks (would have to know the letters or numbers) + + /// + /// Numbers or Letters are known here and defined in atteributes. Or will import for column order based on propereties + /// + /// + /// + /// + /// public List GetInformedImportColumns(Type modelType, FormatType formatType = FormatType.String, int startColumnNumber = 1) { int currentColumnNumber = startColumnNumber; List excelColumnDefinitionArray = new(); + Dictionary columnsUsed = new(); foreach (PropertyInfo item in modelType.GetProperties()) { GetColumnAttributes(modelType, item, formatType, out string modelPropertyName, out string displayName, out ExcelExtensionsColumnAttribute attribute, out FormatType format, out bool required); //TODO: theses all below need to be re though with a new idea of separating the column types out - string letter = attribute?.ExportColumnLetter ?? _excelExtensions.GetColumnLetter(currentColumnNumber); - - List importKeys = attribute?.ImportColumnTitleOptions ?? new List() { modelPropertyName, displayName }; + bool letterValid = string.IsNullOrEmpty(attribute?.ImportColumnLetter) == false; + bool numberValid = attribute?.ImportColumnNumber != null; + + int columnNumber; + if (letterValid && numberValid) + { + if (attribute.ImportColumnNumber != _excelExtensions.GetColumnNumber(attribute.ImportColumnLetter)) + { + throw new Exception($"Two difference values found for import location both {attribute.ImportColumnNumber} as a number, and {attribute.ImportColumnLetter} as a letter."); + } + columnNumber = _excelExtensions.GetColumnNumber(attribute.ImportColumnLetter); + } + else if (letterValid) + { + columnNumber = _excelExtensions.GetColumnNumber(attribute.ImportColumnLetter); + } + else if (numberValid) + { + columnNumber = (int)attribute.ImportColumnNumber; + } + else + { + if (columnsUsed.ContainsKey(currentColumnNumber)) + { + throw new Exception($"{columnsUsed[currentColumnNumber]} already uses col number:{currentColumnNumber}(letter:{_excelExtensions.GetColumnLetter(currentColumnNumber)}). Tried to add {currentColumnNumber} since nothing was assigned to {modelPropertyName}"); + } + else + { + columnsUsed.Add(currentColumnNumber, modelPropertyName); + } + columnNumber = currentColumnNumber; + } + excelColumnDefinitionArray.Add( + new InformedImportColumn(modelPropertyName, + displayName, + columnNumber, + format, + required, + attribute?.DecimalPrecision)); //next column currentColumnNumber++; @@ -70,6 +104,7 @@ public List GetInformedImportColumns(Type modelType, Forma return excelColumnDefinitionArray; } + //1st sets up just for imports in case you need to make tweaks (would have to know the letters or numbers) public List GetUninformedImportColumns(Type modelType, FormatType formatType = FormatType.String, int startColumnNumber = 1) { List excelColumnDefinitionArray = new(); @@ -78,22 +113,21 @@ public List GetUninformedImportColumns(Type modelType, F { GetColumnAttributes(modelType, item, formatType, out string modelPropertyName, out string displayName, out ExcelExtensionsColumnAttribute attribute, out FormatType format, out bool required); - - - // - List importKeys = attribute?.ImportColumnTitleOptions ?? new List() { modelPropertyName, displayName }; + //lets make some title options for default if we don't have any + List titleOptions = attribute?.ImportColumnTitleOptions ?? new List() { modelPropertyName, displayName }; excelColumnDefinitionArray.Add( new UninformedImportColumn(modelPropertyName, displayName, format, required, - importKeys, + titleOptions, attribute?.DecimalPrecision)); } return excelColumnDefinitionArray; } + //3rd, option where you really don't care where you export data because it is in order how you set up your model public List GetInAndOutColumns(Type modelType, FormatType formatType = FormatType.String, int startColumnNumber = 1) { From 25150cf032bd49d7cc6ece7d2e691731e3c96ada Mon Sep 17 00:00:00 2001 From: Dom Schira Date: Mon, 21 Jun 2021 19:44:28 -0700 Subject: [PATCH 08/12] Added to do --- ExcelExtensions/Providers/Import/ImportMapFactory.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ExcelExtensions/Providers/Import/ImportMapFactory.cs b/ExcelExtensions/Providers/Import/ImportMapFactory.cs index 2f9f438..d8292a2 100644 --- a/ExcelExtensions/Providers/Import/ImportMapFactory.cs +++ b/ExcelExtensions/Providers/Import/ImportMapFactory.cs @@ -158,6 +158,10 @@ private void GetColumnAttributes(Type modelType, PropertyInfo item, FormatType f //read the display name attirube modelPropertyName = _excelExtensions.GetExportModelPropertyNameAndDisplayName(modelType, item.Name, out displayName); attribute = item.GetCustomAttribute(); + + + //TODO: throw eroros is tuff is null + //Give the default format if not avail be format = attribute?.Format ?? formatType; required = attribute?.IsRequired ?? true; From 314984d1a86420819d9242f395be63e1f9d2f993 Mon Sep 17 00:00:00 2001 From: Dom Schira Date: Mon, 21 Jun 2021 19:59:45 -0700 Subject: [PATCH 09/12] renamed and moved --- .../Interfaces/Import/IColumnMap.cs | 20 +++ .../Models/Columns/Export/ExportColumn.cs | 6 + .../{ImportMapFactory.cs => ColumnMap.cs} | 144 +++++++++++++----- 3 files changed, 129 insertions(+), 41 deletions(-) create mode 100644 ExcelExtensions/Interfaces/Import/IColumnMap.cs rename ExcelExtensions/Providers/Import/{ImportMapFactory.cs => ColumnMap.cs} (56%) diff --git a/ExcelExtensions/Interfaces/Import/IColumnMap.cs b/ExcelExtensions/Interfaces/Import/IColumnMap.cs new file mode 100644 index 0000000..2dbef28 --- /dev/null +++ b/ExcelExtensions/Interfaces/Import/IColumnMap.cs @@ -0,0 +1,20 @@ +// Copyright (c) Dominic Schira . All Rights Reserved. + +using ExcelExtensions.Models; +using ExcelExtensions.Models.Columns; +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace ExcelExtensions.Providers.Import +{ + public interface IColumnMap + { + int GetAttributeColumnNumber(int currentColumnNumber, Dictionary columnsUsed, string modelPropertyName, ExcelExtensionsColumnAttribute attribute); + void GetColumnAttributes(Type modelType, PropertyInfo item, Enums.Enums.FormatType formatType, out string modelPropertyName, out string displayName, out ExcelExtensionsColumnAttribute attribute, out Enums.Enums.FormatType format, out bool required); + List GetExportColumns(Type modelType, Enums.Enums.FormatType formatType = Enums.Enums.FormatType.String, int startColumnNumber = 1); + List GetInAndOutColumns(Type modelType, Enums.Enums.FormatType formatType = Enums.Enums.FormatType.String, int startColumnNumber = 1); + List GetInformedImportColumns(Type modelType, Enums.Enums.FormatType formatType = Enums.Enums.FormatType.String, int startColumnNumber = 1); + List GetUninformedImportColumns(Type modelType, Enums.Enums.FormatType formatType = Enums.Enums.FormatType.String, int startColumnNumber = 1); + } +} \ No newline at end of file diff --git a/ExcelExtensions/Models/Columns/Export/ExportColumn.cs b/ExcelExtensions/Models/Columns/Export/ExportColumn.cs index 46dd891..3020880 100644 --- a/ExcelExtensions/Models/Columns/Export/ExportColumn.cs +++ b/ExcelExtensions/Models/Columns/Export/ExportColumn.cs @@ -1,6 +1,7 @@ // Copyright (c) Dominic Schira . All Rights Reserved. using ExcelExtensions.Interfaces; +using static ExcelExtensions.Enums.Enums; namespace ExcelExtensions.Models { @@ -24,5 +25,10 @@ public ExportColumn(IExtensions excelExtensions, string exportColumnLetter) : th { } + + public ExportColumn(string modelPropertyName, string displayName, int columnNumber, FormatType format, int? decimalPrecision = null) : base(modelPropertyName, displayName, format, decimalPrecision) + { + ColumnNumber = columnNumber; + } } } diff --git a/ExcelExtensions/Providers/Import/ImportMapFactory.cs b/ExcelExtensions/Providers/Import/ColumnMap.cs similarity index 56% rename from ExcelExtensions/Providers/Import/ImportMapFactory.cs rename to ExcelExtensions/Providers/Import/ColumnMap.cs index d8292a2..2de559a 100644 --- a/ExcelExtensions/Providers/Import/ImportMapFactory.cs +++ b/ExcelExtensions/Providers/Import/ColumnMap.cs @@ -3,44 +3,70 @@ using ExcelExtensions.Interfaces; using ExcelExtensions.Models; using ExcelExtensions.Models.Columns; -using ExcelExtensions.Models.Columns.Import; using System; using System.Collections.Generic; -using System.Linq; using System.Reflection; -using System.Text; -using System.Threading.Tasks; using static ExcelExtensions.Enums.Enums; namespace ExcelExtensions.Providers.Import { - public class ImportMapFactory + /// + /// Provides list of columns from a with or without s + /// + public class ColumnMap : IColumnMap { private readonly IExtensions _excelExtensions; - public ImportMapFactory(IExtensions excelExtensions) + public ColumnMap(IExtensions excelExtensions) { _excelExtensions = excelExtensions; } + //todo: unit test //2nd set up just for exports (would have to know the letters or numbers) + /// + /// If no is provided for a property in the s then the will be used. + /// + /// + /// + /// + /// public List GetExportColumns(Type modelType, FormatType formatType = FormatType.String, int startColumnNumber = 1) { + int currentColumnNumber = startColumnNumber; List excelColumnDefinitionArray = new(); + Dictionary columnsUsed = new(); foreach (PropertyInfo item in modelType.GetProperties()) { - GetColumnAttributes(modelType, item, formatType, out string modelPropertyName, out string displayName, out ExcelExtensionsColumnAttribute attribute, out FormatType format, out bool required); + GetColumnAttributes(modelType, item, formatType, out string modelPropertyName, out string displayName, out ExcelExtensionsColumnAttribute attribute, out FormatType format, out _); + + int columnNumber = GetAttributeColumnNumber(currentColumnNumber, columnsUsed, modelPropertyName, attribute); + + excelColumnDefinitionArray.Add( + new ExportColumn(modelPropertyName, + displayName, + columnNumber, + format, + attribute?.DecimalPrecision)); + + //next column + currentColumnNumber++; } return excelColumnDefinitionArray; } + + + + //todo: unit test //1st sets up just for imports in case you need to make tweaks (would have to know the letters or numbers) /// /// Numbers or Letters are known here and defined in atteributes. Or will import for column order based on propereties + /// If no is provided for a property in the s then the will be used. /// /// /// @@ -57,38 +83,7 @@ public List GetInformedImportColumns(Type modelType, Forma GetColumnAttributes(modelType, item, formatType, out string modelPropertyName, out string displayName, out ExcelExtensionsColumnAttribute attribute, out FormatType format, out bool required); //TODO: theses all below need to be re though with a new idea of separating the column types out - bool letterValid = string.IsNullOrEmpty(attribute?.ImportColumnLetter) == false; - bool numberValid = attribute?.ImportColumnNumber != null; - - int columnNumber; - if (letterValid && numberValid) - { - if (attribute.ImportColumnNumber != _excelExtensions.GetColumnNumber(attribute.ImportColumnLetter)) - { - throw new Exception($"Two difference values found for import location both {attribute.ImportColumnNumber} as a number, and {attribute.ImportColumnLetter} as a letter."); - } - columnNumber = _excelExtensions.GetColumnNumber(attribute.ImportColumnLetter); - } - else if (letterValid) - { - columnNumber = _excelExtensions.GetColumnNumber(attribute.ImportColumnLetter); - } - else if (numberValid) - { - columnNumber = (int)attribute.ImportColumnNumber; - } - else - { - if (columnsUsed.ContainsKey(currentColumnNumber)) - { - throw new Exception($"{columnsUsed[currentColumnNumber]} already uses col number:{currentColumnNumber}(letter:{_excelExtensions.GetColumnLetter(currentColumnNumber)}). Tried to add {currentColumnNumber} since nothing was assigned to {modelPropertyName}"); - } - else - { - columnsUsed.Add(currentColumnNumber, modelPropertyName); - } - columnNumber = currentColumnNumber; - } + int columnNumber = GetAttributeColumnNumber(currentColumnNumber, columnsUsed, modelPropertyName, attribute); excelColumnDefinitionArray.Add( new InformedImportColumn(modelPropertyName, @@ -104,7 +99,64 @@ public List GetInformedImportColumns(Type modelType, Forma return excelColumnDefinitionArray; } + + //todo: unit test + /// + /// + /// + /// + /// + /// + /// + /// + public int GetAttributeColumnNumber(int currentColumnNumber, Dictionary columnsUsed, string modelPropertyName, ExcelExtensionsColumnAttribute attribute) + { + bool letterValid = string.IsNullOrEmpty(attribute?.ImportColumnLetter) == false; + bool numberValid = attribute?.ImportColumnNumber != null; + + int columnNumber; + if (letterValid && numberValid) + { + if (attribute.ImportColumnNumber != _excelExtensions.GetColumnNumber(attribute.ImportColumnLetter)) + { + throw new Exception($"Two difference values found for import location both {attribute.ImportColumnNumber} as a number, and {attribute.ImportColumnLetter} as a letter."); + } + columnNumber = _excelExtensions.GetColumnNumber(attribute.ImportColumnLetter); + } + else if (letterValid) + { + columnNumber = _excelExtensions.GetColumnNumber(attribute.ImportColumnLetter); + } + else if (numberValid) + { + columnNumber = (int)attribute.ImportColumnNumber; + } + else + { + if (columnsUsed.ContainsKey(currentColumnNumber)) + { + throw new Exception($"{columnsUsed[currentColumnNumber]} already uses col number:{currentColumnNumber}(letter:{_excelExtensions.GetColumnLetter(currentColumnNumber)}). Tried to add {currentColumnNumber} since nothing was assigned to {modelPropertyName}"); + } + else + { + columnsUsed.Add(currentColumnNumber, modelPropertyName); + } + columnNumber = currentColumnNumber; + } + + return columnNumber; + } + + //todo: unit test //1st sets up just for imports in case you need to make tweaks (would have to know the letters or numbers) + /// + /// + /// If no is provided for a property in the s then the will be used. + /// + /// + /// + /// + /// public List GetUninformedImportColumns(Type modelType, FormatType formatType = FormatType.String, int startColumnNumber = 1) { List excelColumnDefinitionArray = new(); @@ -127,8 +179,17 @@ public List GetUninformedImportColumns(Type modelType, F return excelColumnDefinitionArray; } - //3rd, option where you really don't care where you export data because it is in order how you set up your model + //todo: unit test + //3rd, option where you really don't care where you export data because it is in order how you set up your model + /// + /// + /// If no is provided for a property in the s then the will be used. + /// + /// + /// + /// + /// public List GetInAndOutColumns(Type modelType, FormatType formatType = FormatType.String, int startColumnNumber = 1) { List excelColumnDefinitionArray = new(); @@ -153,7 +214,8 @@ public List GetInAndOutColumns(Type modelType, FormatType format return excelColumnDefinitionArray; } - private void GetColumnAttributes(Type modelType, PropertyInfo item, FormatType formatType, out string modelPropertyName, out string displayName, out ExcelExtensionsColumnAttribute attribute, out FormatType format, out bool required) + //todo: unit test + public void GetColumnAttributes(Type modelType, PropertyInfo item, FormatType formatType, out string modelPropertyName, out string displayName, out ExcelExtensionsColumnAttribute attribute, out FormatType format, out bool required) { //read the display name attirube modelPropertyName = _excelExtensions.GetExportModelPropertyNameAndDisplayName(modelType, item.Name, out displayName); From 2127fca977730c1d847e49cd9b8a4a38c1417ae7 Mon Sep 17 00:00:00 2001 From: Dom Schira Date: Mon, 21 Jun 2021 20:08:10 -0700 Subject: [PATCH 10/12] namespsces --- .../Interfaces/Export/IExporter.cs | 2 +- ExcelExtensions/Interfaces/IExtensions.cs | 1 + .../Interfaces/Import/IColumnMap.cs | 15 ++++++---- .../Interfaces/Import/Parse/ITableParser.cs | 1 - ExcelExtensions/Models/Columns/Column.cs | 2 +- .../Models/Columns/Export/ExportColumn.cs | 4 +-- .../Columns/Import/ColumnWithSeverity.cs | 29 ------------------- .../Models/Columns/Import/ImportColumn.cs | 18 ++++++++---- .../Columns/Import/InformedImportColumn.cs | 5 ++-- .../Columns/Import/UninformedImportColumn.cs | 5 ++-- .../Models/Columns/InAndOutColumn.cs | 1 + ExcelExtensions/Providers/Export/Exporter.cs | 3 +- ExcelExtensions/Providers/Extensions.cs | 1 + ExcelExtensions/Providers/Import/ColumnMap.cs | 3 ++ .../Providers/Import/Parse/TableParser.cs | 1 - .../Providers/ParseTableTest.cs | 1 + WebApplication/Providers/SampleProvider.cs | 2 ++ 17 files changed, 40 insertions(+), 54 deletions(-) delete mode 100644 ExcelExtensions/Models/Columns/Import/ColumnWithSeverity.cs diff --git a/ExcelExtensions/Interfaces/Export/IExporter.cs b/ExcelExtensions/Interfaces/Export/IExporter.cs index 00fb377..92a3aed 100644 --- a/ExcelExtensions/Interfaces/Export/IExporter.cs +++ b/ExcelExtensions/Interfaces/Export/IExporter.cs @@ -1,6 +1,6 @@ // Copyright (c) Dominic Schira . All Rights Reserved. -using ExcelExtensions.Models; +using ExcelExtensions.Models.Columns; using ExcelExtensions.Models.Export; using OfficeOpenXml; using System.Collections.Generic; diff --git a/ExcelExtensions/Interfaces/IExtensions.cs b/ExcelExtensions/Interfaces/IExtensions.cs index 80314d7..035c81e 100644 --- a/ExcelExtensions/Interfaces/IExtensions.cs +++ b/ExcelExtensions/Interfaces/IExtensions.cs @@ -1,6 +1,7 @@ // Copyright (c) Dominic Schira . All Rights Reserved. using ExcelExtensions.Models; +using ExcelExtensions.Models.Columns; using ExcelExtensions.Models.Columns.Import; using System; using System.Collections.Generic; diff --git a/ExcelExtensions/Interfaces/Import/IColumnMap.cs b/ExcelExtensions/Interfaces/Import/IColumnMap.cs index 2dbef28..79b5cbe 100644 --- a/ExcelExtensions/Interfaces/Import/IColumnMap.cs +++ b/ExcelExtensions/Interfaces/Import/IColumnMap.cs @@ -2,19 +2,22 @@ using ExcelExtensions.Models; using ExcelExtensions.Models.Columns; +using ExcelExtensions.Models.Columns.Export; +using ExcelExtensions.Models.Columns.Import; using System; using System.Collections.Generic; using System.Reflection; +using static ExcelExtensions.Enums.Enums; -namespace ExcelExtensions.Providers.Import +namespace ExcelExtensions.Interfaces.Import { public interface IColumnMap { int GetAttributeColumnNumber(int currentColumnNumber, Dictionary columnsUsed, string modelPropertyName, ExcelExtensionsColumnAttribute attribute); - void GetColumnAttributes(Type modelType, PropertyInfo item, Enums.Enums.FormatType formatType, out string modelPropertyName, out string displayName, out ExcelExtensionsColumnAttribute attribute, out Enums.Enums.FormatType format, out bool required); - List GetExportColumns(Type modelType, Enums.Enums.FormatType formatType = Enums.Enums.FormatType.String, int startColumnNumber = 1); - List GetInAndOutColumns(Type modelType, Enums.Enums.FormatType formatType = Enums.Enums.FormatType.String, int startColumnNumber = 1); - List GetInformedImportColumns(Type modelType, Enums.Enums.FormatType formatType = Enums.Enums.FormatType.String, int startColumnNumber = 1); - List GetUninformedImportColumns(Type modelType, Enums.Enums.FormatType formatType = Enums.Enums.FormatType.String, int startColumnNumber = 1); + void GetColumnAttributes(Type modelType, PropertyInfo item, FormatType formatType, out string modelPropertyName, out string displayName, out ExcelExtensionsColumnAttribute attribute, out FormatType format, out bool required); + List GetExportColumns(Type modelType, FormatType formatType = FormatType.String, int startColumnNumber = 1); + List GetInAndOutColumns(Type modelType, FormatType formatType = FormatType.String, int startColumnNumber = 1); + List GetInformedImportColumns(Type modelType, FormatType formatType = FormatType.String, int startColumnNumber = 1); + List GetUninformedImportColumns(Type modelType, FormatType formatType = FormatType.String, int startColumnNumber = 1); } } \ No newline at end of file diff --git a/ExcelExtensions/Interfaces/Import/Parse/ITableParser.cs b/ExcelExtensions/Interfaces/Import/Parse/ITableParser.cs index 5fac5fe..559ba52 100644 --- a/ExcelExtensions/Interfaces/Import/Parse/ITableParser.cs +++ b/ExcelExtensions/Interfaces/Import/Parse/ITableParser.cs @@ -1,7 +1,6 @@ // Copyright (c) Dominic Schira . All Rights Reserved. using ExcelExtensions.Models; -using ExcelExtensions.Models.Columns; using ExcelExtensions.Models.Columns.Import; using OfficeOpenXml; using System.Collections.Generic; diff --git a/ExcelExtensions/Models/Columns/Column.cs b/ExcelExtensions/Models/Columns/Column.cs index 0137a24..d27b255 100644 --- a/ExcelExtensions/Models/Columns/Column.cs +++ b/ExcelExtensions/Models/Columns/Column.cs @@ -4,7 +4,7 @@ using System; using static ExcelExtensions.Enums.Enums; -namespace ExcelExtensions.Models +namespace ExcelExtensions.Models.Columns { /// /// Represents an excel column diff --git a/ExcelExtensions/Models/Columns/Export/ExportColumn.cs b/ExcelExtensions/Models/Columns/Export/ExportColumn.cs index 3020880..f360c18 100644 --- a/ExcelExtensions/Models/Columns/Export/ExportColumn.cs +++ b/ExcelExtensions/Models/Columns/Export/ExportColumn.cs @@ -3,7 +3,7 @@ using ExcelExtensions.Interfaces; using static ExcelExtensions.Enums.Enums; -namespace ExcelExtensions.Models +namespace ExcelExtensions.Models.Columns.Export { /// /// Represents an excel column @@ -14,7 +14,7 @@ public class ExportColumn : Column /// Represents the location/letter of the excel column. Ex "C" /// Used for exports and import where we know where to look and are not parsing for new col locations /// - public string? ExportColumnLetter { get; } + public string ExportColumnLetter { get; } public ExportColumn(int columnNumber) : base() { diff --git a/ExcelExtensions/Models/Columns/Import/ColumnWithSeverity.cs b/ExcelExtensions/Models/Columns/Import/ColumnWithSeverity.cs deleted file mode 100644 index a2fdf28..0000000 --- a/ExcelExtensions/Models/Columns/Import/ColumnWithSeverity.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) Dominic Schira . All Rights Reserved. - -using static ExcelExtensions.Enums.Enums; - -namespace ExcelExtensions.Models -{ - public class ColumnWithSeverity : Column - { - /// - /// Represent severity if this column is not found while parsing - /// - public ParseExceptionSeverity MissingSeverity { get; set; } - - public ColumnWithSeverity() - { - - } - public ColumnWithSeverity(string modelPropertyName, string displayName, FormatType format, ParseExceptionSeverity missingSeverity = ParseExceptionSeverity.Error, int? decimalPrecision = null) : - base(modelPropertyName, displayName, format, decimalPrecision) - { - MissingSeverity = missingSeverity; - } - public ColumnWithSeverity(Column column, ParseExceptionSeverity missingSeverity = ParseExceptionSeverity.Error) : this(column.ModelProperty, column.DisplayName, column.Format, missingSeverity, column.DecimalPrecision) - { - } - - } - -} diff --git a/ExcelExtensions/Models/Columns/Import/ImportColumn.cs b/ExcelExtensions/Models/Columns/Import/ImportColumn.cs index c9fd80d..54616f0 100644 --- a/ExcelExtensions/Models/Columns/Import/ImportColumn.cs +++ b/ExcelExtensions/Models/Columns/Import/ImportColumn.cs @@ -9,20 +9,26 @@ namespace ExcelExtensions.Models.Columns.Import { - public class ImportColumn : ColumnWithSeverity + public class ImportColumn : Column { public bool IsRequired { get; set; } + /// + /// Represent severity if this column is not found while parsing + /// + public ParseExceptionSeverity MissingSeverity { get; set; } public ImportColumn() : base() { - IsRequired = MissingSeverity == ParseExceptionSeverity.Error; + IsRequired = true; + MissingSeverity = ParseExceptionSeverity.Error; } - public ImportColumn(Column column, bool required) : base(column, required ? ParseExceptionSeverity.Error : ParseExceptionSeverity.Warning) + public ImportColumn(string modelPropertyName, string displayName, FormatType format, bool required = true, int? decimalPrecision = null) : + base(modelPropertyName, displayName, format, decimalPrecision) { - + IsRequired = required; + MissingSeverity = required ? ParseExceptionSeverity.Error : ParseExceptionSeverity.Warning; } - public ImportColumn(string modelPropertyName, string displayName, FormatType format, bool required = true, int? decimalPrecision = null) : - base(modelPropertyName, displayName, format, required ? ParseExceptionSeverity.Error : ParseExceptionSeverity.Warning, decimalPrecision) + public ImportColumn(Column column, bool required) : this(column.ModelProperty, column.DisplayName, column.Format, required, column.DecimalPrecision) { } diff --git a/ExcelExtensions/Models/Columns/Import/InformedImportColumn.cs b/ExcelExtensions/Models/Columns/Import/InformedImportColumn.cs index 18166c5..0d14c6c 100644 --- a/ExcelExtensions/Models/Columns/Import/InformedImportColumn.cs +++ b/ExcelExtensions/Models/Columns/Import/InformedImportColumn.cs @@ -1,9 +1,8 @@ // Copyright (c) Dominic Schira . All Rights Reserved. -using ExcelExtensions.Models.Columns.Import; using static ExcelExtensions.Enums.Enums; -namespace ExcelExtensions.Models.Columns +namespace ExcelExtensions.Models.Columns.Import { /// /// Works for parse and export @@ -27,7 +26,7 @@ public InformedImportColumn(UninformedImportColumn column, int columnNumber) : b } public InformedImportColumn(string modelPropertyName, string displayName, int columnNumber, FormatType format, bool required = true, int? decimalPrecision = null) : - base (modelPropertyName, displayName, format, required, decimalPrecision) + base(modelPropertyName, displayName, format, required, decimalPrecision) { ColumnNumber = columnNumber; } diff --git a/ExcelExtensions/Models/Columns/Import/UninformedImportColumn.cs b/ExcelExtensions/Models/Columns/Import/UninformedImportColumn.cs index 6a6294a..802a370 100644 --- a/ExcelExtensions/Models/Columns/Import/UninformedImportColumn.cs +++ b/ExcelExtensions/Models/Columns/Import/UninformedImportColumn.cs @@ -1,15 +1,14 @@ // Copyright (c) Dominic Schira . All Rights Reserved. using ExcelExtensions.Interfaces; -using ExcelExtensions.Models.Columns.Import; using System; using System.Collections.Generic; using System.Linq; using static ExcelExtensions.Enums.Enums; -namespace ExcelExtensions.Models +namespace ExcelExtensions.Models.Columns.Import { - + /// /// SCAN AND PARSE /// diff --git a/ExcelExtensions/Models/Columns/InAndOutColumn.cs b/ExcelExtensions/Models/Columns/InAndOutColumn.cs index 05feb23..ec73616 100644 --- a/ExcelExtensions/Models/Columns/InAndOutColumn.cs +++ b/ExcelExtensions/Models/Columns/InAndOutColumn.cs @@ -1,5 +1,6 @@ // Copyright (c) Dominic Schira . All Rights Reserved. +using ExcelExtensions.Models.Columns.Import; using System.Collections.Generic; using static ExcelExtensions.Enums.Enums; diff --git a/ExcelExtensions/Providers/Export/Exporter.cs b/ExcelExtensions/Providers/Export/Exporter.cs index a7314fe..9131c80 100644 --- a/ExcelExtensions/Providers/Export/Exporter.cs +++ b/ExcelExtensions/Providers/Export/Exporter.cs @@ -2,7 +2,8 @@ using ExcelExtensions.Interfaces; using ExcelExtensions.Interfaces.Export; -using ExcelExtensions.Models; +using ExcelExtensions.Models.Columns; +using ExcelExtensions.Models.Columns.Export; using ExcelExtensions.Models.Export; using OfficeOpenXml; using System; diff --git a/ExcelExtensions/Providers/Extensions.cs b/ExcelExtensions/Providers/Extensions.cs index 96e9b45..8c6ddac 100644 --- a/ExcelExtensions/Providers/Extensions.cs +++ b/ExcelExtensions/Providers/Extensions.cs @@ -3,6 +3,7 @@ using ExcelExtensions.Globals; using ExcelExtensions.Interfaces; using ExcelExtensions.Models; +using ExcelExtensions.Models.Columns; using ExcelExtensions.Models.Columns.Import; using System; using System.Collections.Generic; diff --git a/ExcelExtensions/Providers/Import/ColumnMap.cs b/ExcelExtensions/Providers/Import/ColumnMap.cs index 2de559a..5973a52 100644 --- a/ExcelExtensions/Providers/Import/ColumnMap.cs +++ b/ExcelExtensions/Providers/Import/ColumnMap.cs @@ -1,8 +1,11 @@ // Copyright (c) Dominic Schira . All Rights Reserved. using ExcelExtensions.Interfaces; +using ExcelExtensions.Interfaces.Import; using ExcelExtensions.Models; using ExcelExtensions.Models.Columns; +using ExcelExtensions.Models.Columns.Export; +using ExcelExtensions.Models.Columns.Import; using System; using System.Collections.Generic; using System.Reflection; diff --git a/ExcelExtensions/Providers/Import/Parse/TableParser.cs b/ExcelExtensions/Providers/Import/Parse/TableParser.cs index 98338b3..91d2431 100644 --- a/ExcelExtensions/Providers/Import/Parse/TableParser.cs +++ b/ExcelExtensions/Providers/Import/Parse/TableParser.cs @@ -9,7 +9,6 @@ using System.Reflection; using static ExcelExtensions.Enums.Enums; using ExcelExtensions.Interfaces; -using ExcelExtensions.Models.Columns; using ExcelExtensions.Models.Columns.Import; namespace ExcelExtensions.Providers.Import.Parse diff --git a/ExcelExtensionsTests/Providers/ParseTableTest.cs b/ExcelExtensionsTests/Providers/ParseTableTest.cs index 097eefb..7b4de4f 100644 --- a/ExcelExtensionsTests/Providers/ParseTableTest.cs +++ b/ExcelExtensionsTests/Providers/ParseTableTest.cs @@ -11,6 +11,7 @@ using Xunit; using static ExcelExtensions.Enums.Enums; using ExcelExtensions.Interfaces; +using ExcelExtensions.Models.Columns.Import; namespace ExcelExtensionsTests { diff --git a/WebApplication/Providers/SampleProvider.cs b/WebApplication/Providers/SampleProvider.cs index f79f84b..3269660 100644 --- a/WebApplication/Providers/SampleProvider.cs +++ b/WebApplication/Providers/SampleProvider.cs @@ -17,6 +17,8 @@ using System.Drawing; using ExcelExtensions.Models.Import; using ExcelExtensions.Models.Export; +using ExcelExtensions.Models.Columns.Import; +using ExcelExtensions.Models.Columns; namespace WebApplication.Providers { From ca365455b3b81f72b72538852feceec64e1ab5f5 Mon Sep 17 00:00:00 2001 From: Dom Schira Date: Mon, 21 Jun 2021 20:55:30 -0700 Subject: [PATCH 11/12] Renamed attribute fixed some colums map and --- .../Interfaces/Import/IColumnMap.cs | 56 ++++++++- ...sColumnAttribute.cs => ColumnAttribute.cs} | 7 +- ExcelExtensions/Providers/Export/Exporter.cs | 2 +- ExcelExtensions/Providers/Extensions.cs | 4 +- ExcelExtensions/Providers/Import/ColumnMap.cs | 118 +++++++++++------- 5 files changed, 131 insertions(+), 56 deletions(-) rename ExcelExtensions/Models/{ExcelExtensionsColumnAttribute.cs => ColumnAttribute.cs} (90%) diff --git a/ExcelExtensions/Interfaces/Import/IColumnMap.cs b/ExcelExtensions/Interfaces/Import/IColumnMap.cs index 79b5cbe..bf6af18 100644 --- a/ExcelExtensions/Interfaces/Import/IColumnMap.cs +++ b/ExcelExtensions/Interfaces/Import/IColumnMap.cs @@ -11,13 +11,65 @@ namespace ExcelExtensions.Interfaces.Import { + //todo fix these comments + /// + /// Provides methods to give to the parse methods from models + /// public interface IColumnMap { - int GetAttributeColumnNumber(int currentColumnNumber, Dictionary columnsUsed, string modelPropertyName, ExcelExtensionsColumnAttribute attribute); - void GetColumnAttributes(Type modelType, PropertyInfo item, FormatType formatType, out string modelPropertyName, out string displayName, out ExcelExtensionsColumnAttribute attribute, out FormatType format, out bool required); + /// + /// + /// + /// + /// + /// + /// + /// + /// + int GetAttributeColumnNumber(bool import, int currentColumnNumber, Dictionary columnsUsed, string modelPropertyName, ColumnAttribute attribute); + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + void GetColumnAttributes(Type modelType, PropertyInfo item, FormatType formatType, out string modelPropertyName, out string displayName, out ColumnAttribute attribute, out FormatType format, out bool required); + /// + /// + /// + /// + /// + /// + /// List GetExportColumns(Type modelType, FormatType formatType = FormatType.String, int startColumnNumber = 1); + /// + /// + /// + /// + /// + /// + /// List GetInAndOutColumns(Type modelType, FormatType formatType = FormatType.String, int startColumnNumber = 1); + /// + /// + /// + /// + /// + /// + /// List GetInformedImportColumns(Type modelType, FormatType formatType = FormatType.String, int startColumnNumber = 1); + /// + /// + /// + /// + /// + /// + /// List GetUninformedImportColumns(Type modelType, FormatType formatType = FormatType.String, int startColumnNumber = 1); } } \ No newline at end of file diff --git a/ExcelExtensions/Models/ExcelExtensionsColumnAttribute.cs b/ExcelExtensions/Models/ColumnAttribute.cs similarity index 90% rename from ExcelExtensions/Models/ExcelExtensionsColumnAttribute.cs rename to ExcelExtensions/Models/ColumnAttribute.cs index b21295b..c203bf7 100644 --- a/ExcelExtensions/Models/ExcelExtensionsColumnAttribute.cs +++ b/ExcelExtensions/Models/ColumnAttribute.cs @@ -10,7 +10,7 @@ namespace ExcelExtensions.Models { [AttributeUsage(AttributeTargets.Property, Inherited = false)] - public class ExcelExtensionsColumnAttribute : Attribute + public class ColumnAttribute : Attribute { /// /// Represent the list of options for the header name @@ -40,7 +40,10 @@ public class ExcelExtensionsColumnAttribute : Attribute public int? ImportColumnNumber { get; set; } - //TODO THROW ERRORS IF BOTH EXPORTS OR BOTH IMPORTS ARE DEFINED + public ColumnAttribute() + { + IsRequired = true; + } } } diff --git a/ExcelExtensions/Providers/Export/Exporter.cs b/ExcelExtensions/Providers/Export/Exporter.cs index 9131c80..cfc5628 100644 --- a/ExcelExtensions/Providers/Export/Exporter.cs +++ b/ExcelExtensions/Providers/Export/Exporter.cs @@ -79,7 +79,7 @@ public void ExportColumns(ref ExcelWorksheet sheet, List rows, List /// /// - private int SetTableHeaderRowNumber(ExcelWorksheet sheet, string displayNameAdditionalText, Column column, int row) + private static int SetTableHeaderRowNumber(ExcelWorksheet sheet, string displayNameAdditionalText, Column column, int row) { CheckForNullColumnNumber(column); if (string.IsNullOrEmpty(displayNameAdditionalText)) diff --git a/ExcelExtensions/Providers/Extensions.cs b/ExcelExtensions/Providers/Extensions.cs index 8c6ddac..bebef40 100644 --- a/ExcelExtensions/Providers/Extensions.cs +++ b/ExcelExtensions/Providers/Extensions.cs @@ -198,9 +198,7 @@ public int FindMaxRow(List cells) /// - public int FindMaxColumn(List columns) - //TODO - => columns.Select(column => column.ColumnNumber).Max(); + public int FindMaxColumn(List columns) => columns.Select(column => (int)column.ColumnNumber).Max(); /// public string AddDecimalPlacesToFormat(Column column, string noDecimals) diff --git a/ExcelExtensions/Providers/Import/ColumnMap.cs b/ExcelExtensions/Providers/Import/ColumnMap.cs index 5973a52..681b08e 100644 --- a/ExcelExtensions/Providers/Import/ColumnMap.cs +++ b/ExcelExtensions/Providers/Import/ColumnMap.cs @@ -14,7 +14,7 @@ namespace ExcelExtensions.Providers.Import { /// - /// Provides list of columns from a with or without s + /// Provides list of columns from a with or without s /// public class ColumnMap : IColumnMap { @@ -30,7 +30,7 @@ public ColumnMap(IExtensions excelExtensions) //todo: unit test //2nd set up just for exports (would have to know the letters or numbers) /// - /// If no is provided for a property in the s then the will be used. + /// If no is provided for a property in the s then the will be used. /// /// /// @@ -44,16 +44,16 @@ public List GetExportColumns(Type modelType, FormatType formatType foreach (PropertyInfo item in modelType.GetProperties()) { - GetColumnAttributes(modelType, item, formatType, out string modelPropertyName, out string displayName, out ExcelExtensionsColumnAttribute attribute, out FormatType format, out _); + GetColumnAttributes(modelType, item, formatType, out string modelPropertyName, out string displayName, out ColumnAttribute attribute, out FormatType format, out _); - int columnNumber = GetAttributeColumnNumber(currentColumnNumber, columnsUsed, modelPropertyName, attribute); + int columnNumber = GetAttributeColumnNumber(false, //export + currentColumnNumber, columnsUsed, modelPropertyName, attribute); - excelColumnDefinitionArray.Add( - new ExportColumn(modelPropertyName, - displayName, - columnNumber, - format, - attribute?.DecimalPrecision)); + excelColumnDefinitionArray.Add(new ExportColumn(modelPropertyName, + displayName, + columnNumber, + format, + attribute?.DecimalPrecision)); //next column currentColumnNumber++; @@ -69,7 +69,7 @@ public List GetExportColumns(Type modelType, FormatType formatType /// /// Numbers or Letters are known here and defined in atteributes. Or will import for column order based on propereties - /// If no is provided for a property in the s then the will be used. + /// If no is provided for a property in the s then the will be used. /// /// /// @@ -83,15 +83,16 @@ public List GetInformedImportColumns(Type modelType, Forma foreach (PropertyInfo item in modelType.GetProperties()) { - GetColumnAttributes(modelType, item, formatType, out string modelPropertyName, out string displayName, out ExcelExtensionsColumnAttribute attribute, out FormatType format, out bool required); + GetColumnAttributes(modelType, item, formatType, out string modelPropertyName, out string displayName, out ColumnAttribute attribute, out FormatType format, out bool required); //TODO: theses all below need to be re though with a new idea of separating the column types out - int columnNumber = GetAttributeColumnNumber(currentColumnNumber, columnsUsed, modelPropertyName, attribute); + int columnNumber = GetAttributeColumnNumber(true, //import + currentColumnNumber, columnsUsed, modelPropertyName, attribute); excelColumnDefinitionArray.Add( new InformedImportColumn(modelPropertyName, - displayName, - columnNumber, + displayName, //title + columnNumber, //excel column location number format, required, attribute?.DecimalPrecision)); @@ -105,40 +106,44 @@ public List GetInformedImportColumns(Type modelType, Forma //todo: unit test /// - /// + /// Gets column number from the /// + /// /// /// /// /// /// - public int GetAttributeColumnNumber(int currentColumnNumber, Dictionary columnsUsed, string modelPropertyName, ExcelExtensionsColumnAttribute attribute) + public int GetAttributeColumnNumber(bool import, int currentColumnNumber, Dictionary columnsUsed, string modelPropertyName, ColumnAttribute attribute) { - bool letterValid = string.IsNullOrEmpty(attribute?.ImportColumnLetter) == false; - bool numberValid = attribute?.ImportColumnNumber != null; + bool letterValid = import ? string.IsNullOrEmpty(attribute?.ImportColumnLetter) == false : string.IsNullOrEmpty(attribute?.ExportColumnLetter) == false; + bool numberValid = import ? attribute?.ImportColumnNumber != null : attribute?.ExportColumnNumber != null; int columnNumber; if (letterValid && numberValid) { - if (attribute.ImportColumnNumber != _excelExtensions.GetColumnNumber(attribute.ImportColumnLetter)) + int columnLetterValue = getColumnNumberFromLetter(import, attribute); + int colNum = getColumnNumber(import, attribute); + + if (colNum != columnLetterValue) { - throw new Exception($"Two difference values found for import location both {attribute.ImportColumnNumber} as a number, and {attribute.ImportColumnLetter} as a letter."); + throw new Exception($"Two difference values found for import {ErrorLocation(columnLetterValue)} as letter and {ErrorLocation(colNum)} as number."); } - columnNumber = _excelExtensions.GetColumnNumber(attribute.ImportColumnLetter); + columnNumber = columnLetterValue; } else if (letterValid) { - columnNumber = _excelExtensions.GetColumnNumber(attribute.ImportColumnLetter); + columnNumber = getColumnNumberFromLetter(import, attribute); ; } else if (numberValid) { - columnNumber = (int)attribute.ImportColumnNumber; + columnNumber = getColumnNumber(import, attribute); } else { if (columnsUsed.ContainsKey(currentColumnNumber)) { - throw new Exception($"{columnsUsed[currentColumnNumber]} already uses col number:{currentColumnNumber}(letter:{_excelExtensions.GetColumnLetter(currentColumnNumber)}). Tried to add {currentColumnNumber} since nothing was assigned to {modelPropertyName}"); + throw new Exception($"{columnsUsed[currentColumnNumber]} already uses column {ErrorLocation(currentColumnNumber)}. Tried to add {currentColumnNumber} since nothing was assigned to {modelPropertyName}"); } else { @@ -148,13 +153,25 @@ public int GetAttributeColumnNumber(int currentColumnNumber, Dictionary $"(number:{currentColumnNumber})(letter:{_excelExtensions.GetColumnLetter(currentColumnNumber)}"; + //todo: unit test //1st sets up just for imports in case you need to make tweaks (would have to know the letters or numbers) /// /// - /// If no is provided for a property in the s then the will be used. + /// If no is provided for a property in the s then the will be used. /// /// /// @@ -162,32 +179,38 @@ public int GetAttributeColumnNumber(int currentColumnNumber, Dictionary public List GetUninformedImportColumns(Type modelType, FormatType formatType = FormatType.String, int startColumnNumber = 1) { - List excelColumnDefinitionArray = new(); + List uninformedImportColumns = new(); foreach (PropertyInfo item in modelType.GetProperties()) { - GetColumnAttributes(modelType, item, formatType, out string modelPropertyName, out string displayName, out ExcelExtensionsColumnAttribute attribute, out FormatType format, out bool required); + GetColumnAttributes(modelType, item, formatType, out string modelPropertyName, out string displayName, out ColumnAttribute attribute, out FormatType format, out bool required); - //lets make some title options for default if we don't have any - List titleOptions = attribute?.ImportColumnTitleOptions ?? new List() { modelPropertyName, displayName }; + List defualtTitles = new() { modelPropertyName, displayName }; + //if null use default tiles + List titleOptions = attribute?.ImportColumnTitleOptions ?? defualtTitles; - excelColumnDefinitionArray.Add( - new UninformedImportColumn(modelPropertyName, - displayName, - format, - required, - titleOptions, - attribute?.DecimalPrecision)); + //if not null but empty still use the default tiles + if (titleOptions.Count > 0) + { + titleOptions.AddRange(defualtTitles); + } + + uninformedImportColumns.Add(new UninformedImportColumn(modelPropertyName, + displayName,//title + format, + required, + titleOptions, //used to search for in parse table header + attribute?.DecimalPrecision)); } - return excelColumnDefinitionArray; + return uninformedImportColumns; } //todo: unit test //3rd, option where you really don't care where you export data because it is in order how you set up your model /// /// - /// If no is provided for a property in the s then the will be used. + /// If no is provided for a property in the s then the will be used. /// /// /// @@ -195,34 +218,33 @@ public List GetUninformedImportColumns(Type modelType, F /// public List GetInAndOutColumns(Type modelType, FormatType formatType = FormatType.String, int startColumnNumber = 1) { - List excelColumnDefinitionArray = new(); + List inAndOutColumns = new(); int currentColumnNumber = startColumnNumber; foreach (PropertyInfo item in modelType.GetProperties()) { - GetColumnAttributes(modelType, item, formatType, out string modelPropertyName, out string displayName, out ExcelExtensionsColumnAttribute attribute, out FormatType format, out bool required); + GetColumnAttributes(modelType, item, formatType, out string modelPropertyName, out string displayName, out ColumnAttribute attribute, out FormatType format, out bool required); List importKeys = attribute?.ImportColumnTitleOptions ?? new List() { modelPropertyName, displayName }; - excelColumnDefinitionArray.Add( - new InAndOutColumn(modelPropertyName, - displayName, // - currentColumnNumber++, //export location + inAndOutColumns.Add(new InAndOutColumn(modelPropertyName, + displayName, //title + currentColumnNumber++, //import/export location format, required, importKeys, attribute?.DecimalPrecision)); } - return excelColumnDefinitionArray; + return inAndOutColumns; } //todo: unit test - public void GetColumnAttributes(Type modelType, PropertyInfo item, FormatType formatType, out string modelPropertyName, out string displayName, out ExcelExtensionsColumnAttribute attribute, out FormatType format, out bool required) + public void GetColumnAttributes(Type modelType, PropertyInfo item, FormatType formatType, out string modelPropertyName, out string displayName, out ColumnAttribute attribute, out FormatType format, out bool required) { //read the display name attirube modelPropertyName = _excelExtensions.GetExportModelPropertyNameAndDisplayName(modelType, item.Name, out displayName); - attribute = item.GetCustomAttribute(); + attribute = item.GetCustomAttribute(); //TODO: throw eroros is tuff is null From 2210c4003f55d8f81b9984e249b40d0cc1c0f084 Mon Sep 17 00:00:00 2001 From: Dom Schira Date: Mon, 21 Jun 2021 21:18:29 -0700 Subject: [PATCH 12/12] Now the package level builds --- ExcelExtensions/Models/ColumnAttribute.cs | 52 +++++++++++++++++++---- ExcelExtensions/Providers/Extensions.cs | 1 - 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/ExcelExtensions/Models/ColumnAttribute.cs b/ExcelExtensions/Models/ColumnAttribute.cs index c203bf7..a21df78 100644 --- a/ExcelExtensions/Models/ColumnAttribute.cs +++ b/ExcelExtensions/Models/ColumnAttribute.cs @@ -2,27 +2,30 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.ComponentModel.DataAnnotations; +using System.Reflection; using static ExcelExtensions.Enums.Enums; namespace ExcelExtensions.Models { + /// + /// Provides extensions to models for import and export with excel extensions + /// [AttributeUsage(AttributeTargets.Property, Inherited = false)] public class ColumnAttribute : Attribute { /// /// Represent the list of options for the header name + /// Default will look at the and the /// public List ImportColumnTitleOptions { get; set; } /// - /// If required then if not then warning + /// If required then if not then /// - public bool? IsRequired { get; set; } + public bool IsRequired { get; set; } - //Might be albe to depricate this + //Might be able to deprecate this ????????? who knows yet /// /// Represents the format type for the excel object /// @@ -32,12 +35,21 @@ public class ColumnAttribute : Attribute /// public int? DecimalPrecision { get; set; } + /// + /// Represents the export location + /// public string? ExportColumnLetter { get; set; } - + /// + /// Represents the export location + /// public int? ExportColumnNumber { get; set; } - + /// + /// Represents the import location + /// public string? ImportColumnLetter { get; set; } - + /// + /// Represents the import location + /// public int? ImportColumnNumber { get; set; } public ColumnAttribute() @@ -45,5 +57,27 @@ public ColumnAttribute() IsRequired = true; } + //todo summary + /// + /// + /// + /// + /// + /// + public ColumnAttribute(FormatType format, List titleOptions = null, int? precision = null) + { + if (titleOptions is not null) + { + ImportColumnTitleOptions = titleOptions; + } + + if (precision is not null) + { + DecimalPrecision = precision; + } + + Format = format; + IsRequired = true; + } } } diff --git a/ExcelExtensions/Providers/Extensions.cs b/ExcelExtensions/Providers/Extensions.cs index bebef40..a5ccfde 100644 --- a/ExcelExtensions/Providers/Extensions.cs +++ b/ExcelExtensions/Providers/Extensions.cs @@ -228,7 +228,6 @@ public string GetExportModelPropertyNameAndDisplayName(Type objType, string mode { try { - //TODO make custome attribute and read info from here MemberInfo property = objType.GetProperty(modelPropertyName); TextInfo usEnglishTextInfo = new CultureInfo("en-US", false).TextInfo;