Skip to content

Commit

Permalink
Merge pull request #127 from donnytian/develop
Browse files Browse the repository at this point in the history
v6.2
  • Loading branch information
donnytian committed Oct 22, 2023
2 parents 27a06eb + 7ee9651 commit d486a94
Show file tree
Hide file tree
Showing 19 changed files with 2,976 additions and 2,769 deletions.
986 changes: 493 additions & 493 deletions Npoi.Mapper/src/Npoi.Mapper/AnonymousTypeFactory.cs

Large diffs are not rendered by default.

477 changes: 276 additions & 201 deletions Npoi.Mapper/src/Npoi.Mapper/Attributes/ColumnAttribute.cs

Large diffs are not rendered by default.

15 changes: 7 additions & 8 deletions Npoi.Mapper/src/Npoi.Mapper/Attributes/IgnoreAttribute.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
using System;

namespace Npoi.Mapper.Attributes
namespace Npoi.Mapper.Attributes;

/// <summary>
/// Specifies to ignore a property for mapping.
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public sealed class IgnoreAttribute : Attribute
{
/// <summary>
/// Specifies to ignore a property for mapping.
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public sealed class IgnoreAttribute : Attribute
{
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
using System;

namespace Npoi.Mapper.Attributes
namespace Npoi.Mapper.Attributes;

/// <summary>
/// Specifies to use the last non-blank value when reading from cells for this property.
/// Typically handle the blank error in merged cells.
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public sealed class UseLastNonBlankValueAttribute : Attribute
{
/// <summary>
/// Specifies to use the last non-blank value when reading from cells for this property.
/// Typically handle the blank error in merged cells.
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public sealed class UseLastNonBlankValueAttribute : Attribute
{
}
}
279 changes: 134 additions & 145 deletions Npoi.Mapper/src/Npoi.Mapper/ColumnInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,175 +4,164 @@
using Npoi.Mapper.Attributes;
using NPOI.SS.UserModel;

namespace Npoi.Mapper
namespace Npoi.Mapper;

/// <summary>
/// Information required for one column when mapping between object and file rows.
/// </summary>
public class ColumnInfo : IColumnInfo
{
#region Fields

// For cache purpose, avoid lookup style dictionary for every cell.
private ICellStyle _headerStyle;
private ICellStyle _dataStyle;
private bool _headerStyleCached;
private bool _dataStyleCached;

#endregion

#region Properties

/// <summary>
/// Value for the column header.
/// </summary>
public object HeaderValue { get; set; }

/// <summary>
/// The mapped property information.
/// </summary>
public ColumnAttribute Attribute { get; set; }

/// <summary>
/// The last non-blank cell value.
/// </summary>
public object LastNonBlankValue { get; set; }

/// <summary>
/// The current cell value, might be used for custom resolving.
/// </summary>
public object CurrentValue { get; set; }

/// <summary>
/// Get or set the header cell format.
/// </summary>
public short? HeaderFormat { get; set; }

/// <summary>
/// Get or set the data cell format.
/// </summary>
public short? DataFormat { get; set; }

/// <summary>
/// Object that associated with the current row.
/// </summary>
public object RowTag { get; set; }

#endregion

#region Constructors

/// <summary>
/// Information required for one column when mapping between object and file rows.
/// Initialize a new instance of <see cref="ColumnInfo"/> class.
/// </summary>
public class ColumnInfo : IColumnInfo
/// <param name="headerValue">The header value</param>
/// <param name="columnIndex">The column index.</param>
public ColumnInfo(object headerValue, int columnIndex)
{
#region Fields

// For cache purpose, avoid lookup style dictionary for every cell.
private ICellStyle _headerStyle;
private ICellStyle _dataStyle;
private bool _headerStyleCached;
private bool _dataStyleCached;

#endregion

#region Properties

/// <summary>
/// Value for the column header.
/// </summary>
public object HeaderValue { get; set; }

/// <summary>
/// The mapped property information.
/// </summary>
public ColumnAttribute Attribute { get; set; }

/// <summary>
/// The last non-blank cell value.
/// </summary>
public object LastNonBlankValue { get; set; }

/// <summary>
/// The current cell value, might be used for custom resolving.
/// </summary>
public object CurrentValue { get; set; }

/// <summary>
/// Get or set the header cell format.
/// </summary>
public short? HeaderFormat { get; set; }

/// <summary>
/// Get or set the data cell format.
/// </summary>
public short? DataFormat { get; set; }

/// <summary>
/// Object that associated with the current row.
/// </summary>
public object RowTag { get; set; }

#endregion

#region Constructors

/// <summary>
/// Initialize a new instance of <see cref="ColumnInfo"/> class.
/// </summary>
/// <param name="headerValue">The header value</param>
/// <param name="columnName">The column name.</param>
/// <param name="pi">The mapped PropertyInfo.</param>
public ColumnInfo(object headerValue, string columnName, PropertyInfo pi)
{
HeaderValue = headerValue;
Attribute = new ColumnAttribute()
{
Name = columnName,
Property = pi
};
}
HeaderValue = headerValue;
Attribute = new ColumnAttribute { Index = columnIndex };
}

/// <summary>
/// Initialize a new instance of <see cref="ColumnInfo"/> class.
/// </summary>
/// <param name="headerValue">The header value</param>
/// <param name="columnIndex">The column index.</param>
/// <param name="pi">The mapped PropertyInfo.</param>
public ColumnInfo(object headerValue, int columnIndex, PropertyInfo pi)
{
HeaderValue = headerValue;
Attribute = new ColumnAttribute()
{
Index = columnIndex,
Property = pi
};
}
/// <summary>
/// Initialize a new instance of <see cref="ColumnInfo"/> class.
/// </summary>
/// <param name="headerValue">The header value</param>
/// <param name="columnIndex">The column index.</param>
/// <param name="pi">The mapped PropertyInfo.</param>
/// <param name="hostTypeName">The host type name.</param>
/// <param name="propertyPath">The property path.</param>
public ColumnInfo(object headerValue, int columnIndex, PropertyInfo pi, string hostTypeName, string propertyPath)
{
HeaderValue = headerValue;
Attribute = new ColumnAttribute { Index = columnIndex }.SetProperty(pi, hostTypeName, propertyPath);
}

/// <summary>
/// Initialize a new instance of <see cref="ColumnInfo"/> class.
/// </summary>
/// <param name="headerValue">The header value</param>
/// <param name="attribute">Mapped <c>PropertyMeta</c> object.</param>
public ColumnInfo(object headerValue, ColumnAttribute attribute)
{
if (attribute == null)
throw new ArgumentNullException(nameof(attribute));
/// <summary>
/// Initialize a new instance of <see cref="ColumnInfo"/> class.
/// </summary>
/// <param name="headerValue">The header value</param>
/// <param name="attribute">Mapped <c>PropertyMeta</c> object.</param>
public ColumnInfo(object headerValue, ColumnAttribute attribute)
{
Attribute = attribute ?? throw new ArgumentNullException(nameof(attribute));
HeaderValue = headerValue;
}

Attribute = attribute;
HeaderValue = headerValue;
}
#endregion

#endregion
#region Public Methods

#region Public Methods
/// <summary>
/// Refresh LastNonBlankValue and CurrentValue property then return value according UseLastNonBlankValue property.
/// </summary>
/// <param name="value">The current cell value.</param>
/// <returns>
/// Same object as input parameter if UseLastNonBlankValue is false;
/// otherwise return LastNonBlankValue.
/// </returns>
public object RefreshAndGetValue(object value)
{
CurrentValue = value;

/// <summary>
/// Refresh LastNonBlankValue and CurrentValue property then return value according UseLastNonBlankValue property.
/// </summary>
/// <param name="value">The current cell value.</param>
/// <returns>
/// Same object as input parameter if UseLastNonBlankValue is false;
/// otherwise return LastNonBlankValue.
/// </returns>
public object RefreshAndGetValue(object value)
if (value == null || string.IsNullOrWhiteSpace(value as string))
{
CurrentValue = value;
return Attribute.UseLastNonBlankValue == true ? LastNonBlankValue : value;
}

if (value == null || string.IsNullOrWhiteSpace(value as string))
{
return Attribute.UseLastNonBlankValue == true ? LastNonBlankValue : value;
}
LastNonBlankValue = value;

LastNonBlankValue = value;
return value;
}

return value;
}
/// <summary>
/// Set style of the cell for export.
/// Assume the cell belongs to current column.
/// </summary>
/// <param name="cell">The cell to be set.</param>
/// <param name="value">The cell value object.</param>
/// <param name="isHeader">If <c>true</c>, use HeaderFormat; otherwise use DataFormat.</param>
/// <param name="defaultFormats">The default formats dictionary.</param>
/// <param name="helper">The helper object.</param>
public void SetCellStyle(ICell cell, object value, bool isHeader, Dictionary<Type, string> defaultFormats, MapHelper helper)
{
if (cell == null) throw new ArgumentNullException(nameof(cell));

/// <summary>
/// Set style of the cell for export.
/// Assume the cell belongs to current column.
/// </summary>
/// <param name="cell">The cell to be set.</param>
/// <param name="value">The cell value object.</param>
/// <param name="isHeader">If <c>true</c>, use HeaderFormat; otherwise use DataFormat.</param>
/// <param name="defaultFormats">The default formats dictionary.</param>
/// <param name="helper">The helper object.</param>
public void SetCellStyle(ICell cell, object value, bool isHeader, Dictionary<Type, string> defaultFormats, MapHelper helper)
if (isHeader && !_headerStyleCached)
{
if (cell == null) throw new ArgumentNullException(nameof(cell));
_headerStyle = helper.GetCellStyle(cell, null, HeaderFormat);

if (isHeader && !_headerStyleCached)
if (_headerStyle == null && HeaderValue != null)
{
_headerStyle = helper.GetCellStyle(cell, null, HeaderFormat);

if (_headerStyle == null && HeaderValue != null)
{
_headerStyle = helper.GetDefaultStyle(cell.Sheet.Workbook, HeaderValue, defaultFormats);
}

_headerStyleCached = true;
_headerStyle = helper.GetDefaultStyle(cell.Sheet.Workbook, HeaderValue, defaultFormats);
}
else if (!isHeader && !_dataStyleCached)
{
_dataStyle = helper.GetCellStyle(cell, Attribute.CustomFormat, DataFormat);

if (_dataStyle == null && value != null)
{
_dataStyle = helper.GetDefaultStyle(cell.Sheet.Workbook, value, defaultFormats);
}
_headerStyleCached = true;
}
else if (!isHeader && !_dataStyleCached)
{
_dataStyle = helper.GetCellStyle(cell, Attribute.CustomFormat, DataFormat);

_dataStyleCached = true;
if (_dataStyle == null && value != null)
{
_dataStyle = helper.GetDefaultStyle(cell.Sheet.Workbook, value, defaultFormats);
}

cell.CellStyle = isHeader ? _headerStyle : _dataStyle;
_dataStyleCached = true;
}

#endregion
cell.CellStyle = isHeader ? _headerStyle : _dataStyle;
}

#endregion
}
32 changes: 16 additions & 16 deletions Npoi.Mapper/src/Npoi.Mapper/Extensions/EnumerableExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
using System;
using System.Collections.Generic;

namespace Npoi.Mapper
// ReSharper disable once CheckNamespace
namespace Npoi.Mapper;

/// <summary>
/// Provides extensions for <see cref="IEnumerable{T}"/> class.
/// </summary>
public static class EnumerableExtensions
{
/// <summary>
/// Provides extensions for <see cref="IEnumerable{T}"/> class.
/// Extension for <see cref="IEnumerable{T}"/> object to handle each item.
/// </summary>
public static class EnumerableExtensions
/// <typeparam name="T">The item type.</typeparam>
/// <param name="sequence">The enumerable sequence.</param>
/// <param name="action">Action to apply to each item.</param>
public static void ForEach<T>(this IEnumerable<T> sequence, Action<T> action)
{
/// <summary>
/// Extension for <see cref="IEnumerable{T}"/> object to handle each item.
/// </summary>
/// <typeparam name="T">The item type.</typeparam>
/// <param name="sequence">The enumerable sequence.</param>
/// <param name="action">Action to apply to each item.</param>
public static void ForEach<T>(this IEnumerable<T> sequence, Action<T> action)
{
if (sequence == null) return;
if (sequence == null) return;

foreach (var item in sequence)
{
action(item);
}
foreach (var item in sequence)
{
action(item);
}
}
}
Loading

0 comments on commit d486a94

Please sign in to comment.