[New] Add a merge attribute

This commit is contained in:
罗威 2022-04-02 23:22:52 +08:00
parent 694196f8b6
commit 4868c77ec8
7 changed files with 141 additions and 16 deletions

View File

@ -0,0 +1,50 @@
using System;
using MiniExcelLibs.Utils;
namespace MiniExcelLibs.Attributes
{
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
public class ExcelColumnAttribute : Attribute
{
private int _index = -1;
private string _xName;
public string Name { get; set; }
public string[] Aliases { get; set; }
public double Width { get; set; }
public string Format { get; set; }
public bool Ignore { get; set; }
public int Index
{
get => _index;
set => Init(value);
}
public string XName
{
get => _xName;
set => Init(ColumnHelper.GetColumnIndex(value), value);
}
private void Init(int index, string columnName = null)
{
if (index == null || index < 0)
{
throw new ArgumentOutOfRangeException(nameof(index), index,
$"Column index {index} must be greater or equal to zero.");
}
if (_xName == null)
if (columnName != null)
_xName = columnName;
else
_xName = ColumnHelper.GetAlphabetColumnName(index);
_index = index;
}
}
}

View File

@ -371,11 +371,11 @@ namespace MiniExcelLibs.OpenXml
{
string cellValueStr;
//TODO:c.SetAttribute("t", "d"); and custom format
var efa = propInfo.Value.PropertyInfo.GetCustomAttribute(typeof(ExcelFormatAttribute)) as ExcelFormatAttribute;
if (efa == null)
cellValueStr = (cellValue as DateTime?)?.ToString("yyyy-MM-dd HH:mm:ss");
else
cellValueStr = (cellValue as DateTime?)?.ToString(efa.Format);
var format = propInfo.Value.PropertyInfo.GetAttributeValue((ExcelFormatAttribute x) => x.Format)
?? propInfo.Value.PropertyInfo.GetAttributeValue((ExcelColumnAttribute x) => x.Format)
?? "yyyy-MM-dd HH:mm:ss";
cellValueStr = (cellValue as DateTime?)?.ToString(format);
return cellValueStr;
}

View File

@ -51,7 +51,10 @@
internal static List<ExcelCustomPropertyInfo> GetSaveAsProperties(this Type type)
{
List<ExcelCustomPropertyInfo> props = GetExcelPropertyInfo(type, BindingFlags.Public | BindingFlags.Instance)
.Where(prop => prop.Property.GetGetMethod() != null && !prop.Property.GetAttributeValue((ExcelIgnoreAttribute x) => x.ExcelIgnore))
.Where(prop => prop.Property.GetGetMethod() != null
&& !prop.Property.GetAttributeValue((ExcelIgnoreAttribute x) => x.ExcelIgnore)
&& !prop.Property.GetAttributeValue((ExcelColumnAttribute x) => x.Ignore)
)
.ToList() /*ignore without set*/;
if (props.Count == 0)
@ -101,7 +104,9 @@
internal static List<ExcelCustomPropertyInfo> GetExcelCustomPropertyInfos(Type type, string[] keys)
{
List<ExcelCustomPropertyInfo> props = GetExcelPropertyInfo(type, BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.Instance)
.Where(prop => prop.Property.GetSetMethod() != null && !prop.Property.GetAttributeValue((ExcelIgnoreAttribute x) => x.ExcelIgnore))
.Where(prop => prop.Property.GetSetMethod() != null
&& !prop.Property.GetAttributeValue((ExcelIgnoreAttribute x) => x.ExcelIgnore)
&& !prop.Property.GetAttributeValue((ExcelColumnAttribute x) => x.Ignore))
.ToList() /*ignore without set*/;
if (props.Count == 0)
@ -152,17 +157,19 @@
var excelColumnName = p.GetAttribute<ExcelColumnNameAttribute>() ;
var excludeNullableType = gt ?? p.PropertyType;
var excelFormat = p.GetAttribute<ExcelFormatAttribute>()?.Format;
var excelColumn = p.GetAttribute<ExcelColumnAttribute>();
var excelColumnIndex = excelColumn?.Index > -1 ? excelColumn.Index : (int?)null;
return new ExcelCustomPropertyInfo
{
Property = p,
ExcludeNullableType = excludeNullableType,
Nullable = gt != null,
ExcelColumnAliases = excelColumnName?.Aliases,
ExcelColumnName = excelColumnName?.ExcelColumnName ?? p.GetAttribute<System.ComponentModel.DisplayNameAttribute>()?.DisplayName ?? p.Name ,
ExcelColumnIndex = p.GetAttribute<ExcelColumnIndexAttribute>()?.ExcelColumnIndex,
ExcelXName = p.GetAttribute<ExcelColumnIndexAttribute>()?.ExcelXName,
ExcelColumnWidth = p.GetAttribute<ExcelColumnWidthAttribute>()?.ExcelColumnWidth,
ExcelFormat = excelFormat,
ExcelColumnAliases = excelColumnName?.Aliases ?? excelColumn?.Aliases,
ExcelColumnName = excelColumnName?.ExcelColumnName ?? p.GetAttribute<System.ComponentModel.DisplayNameAttribute>()?.DisplayName ?? excelColumn?.Name ?? p.Name,
ExcelColumnIndex = p.GetAttribute<ExcelColumnIndexAttribute>()?.ExcelColumnIndex ?? excelColumnIndex,
ExcelXName = p.GetAttribute<ExcelColumnIndexAttribute>()?.ExcelXName ?? excelColumn?.XName,
ExcelColumnWidth = p.GetAttribute<ExcelColumnWidthAttribute>()?.ExcelColumnWidth ?? excelColumn?.Width,
ExcelFormat = excelFormat ?? excelColumn?.Format,
};
});
}

View File

@ -41,24 +41,26 @@ namespace MiniExcelLibs.Tests
var value = new
{
Issue255DTO = new Issue255DTO[] {
new Issue255DTO { Time = new DateTime(2021, 01, 01) }
new Issue255DTO { Time = new DateTime(2021, 01, 01), Time2 = new DateTime(2021, 01, 01) }
}
};
await MiniExcel.SaveAsByTemplateAsync(path, templatePath, value);
var q = await MiniExcel.QueryAsync(path);
var rows = q.ToList();
Assert.Equal("2021", rows[1].A.ToString());
Assert.Equal("2021", rows[1].B.ToString());
}
//saveas
{
var path = PathHelper.GetTempPath();
var value = new Issue255DTO[] {
new Issue255DTO { Time = new DateTime(2021, 01, 01) }
new Issue255DTO { Time = new DateTime(2021, 01, 01), Time2 = new DateTime(2021, 01, 01) }
};
await MiniExcel.SaveAsAsync(path, value);
var q = await MiniExcel.QueryAsync(path);
var rows = q.ToList();
Assert.Equal("2021", rows[1].A.ToString());
Assert.Equal("2021", rows[1].B.ToString());
}
}
@ -66,6 +68,9 @@ namespace MiniExcelLibs.Tests
{
[ExcelFormat("yyyy")]
public DateTime Time { get; set; }
[ExcelColumn(Format = "yyyy")]
public DateTime Time2 { get; set; }
}
/// <summary>

View File

@ -1319,12 +1319,13 @@ Henry,44,Jerry,44
var value = new
{
Issue255DTO = new Issue255DTO[] {
new Issue255DTO { Time = new DateTime(2021, 01, 01) }
new Issue255DTO { Time = new DateTime(2021, 01, 01), Time2 = new DateTime(2021, 01, 01) }
}
};
MiniExcel.SaveAsByTemplate(path, templatePath, value);
var rows = MiniExcel.Query(path).ToList();
Assert.Equal("2021", rows[1].A.ToString());
Assert.Equal("2021", rows[1].B.ToString());
}
//saveas
{
@ -1342,6 +1343,9 @@ Henry,44,Jerry,44
{
[ExcelFormat("yyyy")]
public DateTime Time { get; set; }
[ExcelColumn(Format = "yyyy")]
public DateTime Time2 { get; set; }
}
/// <summary>

View File

@ -64,6 +64,22 @@ namespace MiniExcelLibs.Tests
[ExcelColumnIndex(3)] // start with 0
public string Test7 { get; set; }
}
public class ExcelAttributeDemo2
{
[ExcelColumn(Name = "Column1")]
public string Test1 { get; set; }
[ExcelColumn(Name = "Column2")]
public string Test2 { get; set; }
[ExcelColumn(Ignore = true)]
public string Test3 { get; set; }
[ExcelColumn(XName = "I")] // system will convert "I" to 8 index
public string Test4 { get; set; }
public string Test5 { get; } //wihout set will ignore
public string Test6 { get; private set; } //un-public set will ignore
[ExcelColumn(Index = 3)] // start with 0
public string Test7 { get; set; }
}
[Fact]
public async Task CustomAttributeWihoutVaildPropertiesTest()
@ -89,6 +105,20 @@ namespace MiniExcelLibs.Tests
Assert.Null(rows[0].Test6);
Assert.Equal("Test4", rows[0].Test7);
}
[Fact]
public async Task QueryCustomAttributes2Test()
{
var path = @"../../../../../samples/xlsx/TestCustomExcelColumnAttribute.xlsx";
var rows = (await MiniExcel.QueryAsync<ExcelAttributeDemo2>(path)).ToList();
Assert.Equal("Column1", rows[0].Test1);
Assert.Equal("Column2", rows[0].Test2);
Assert.Null(rows[0].Test3);
Assert.Equal("Test7", rows[0].Test4);
Assert.Null(rows[0].Test5);
Assert.Null(rows[0].Test6);
Assert.Equal("Test4", rows[0].Test7);
}
[Fact]
public async Task SaveAsCustomAttributesTest()
@ -118,6 +148,35 @@ namespace MiniExcelLibs.Tests
Assert.Equal(3, rows.Count);
}
}
[Fact]
public async Task SaveAsCustomAttributes2Test()
{
string path = GetTempXlsxPath();
var input = Enumerable.Range(1, 3).Select(
s => new ExcelAttributeDemo2
{
Test1 = "Test1",
Test2 = "Test2",
Test3 = "Test3",
Test4 = "Test4",
}
);
await MiniExcel.SaveAsAsync(path, input);
{
var d = await MiniExcel.QueryAsync(path, true);
var rows = d.ToList();
var first = rows[0] as IDictionary<string, object>;
Assert.Equal(new[] { "Column1", "Column2", "Test5", "Test7", "Test6", "Test4" }, first.Keys);
Assert.Equal("Test1", rows[0].Column1);
Assert.Equal("Test2", rows[0].Column2);
Assert.Equal("Test4", rows[0].Test4);
Assert.Null(rows[0].Test5);
Assert.Null(rows[0].Test6);
Assert.Equal(3, rows.Count);
}
}
private static string GetTempXlsxPath()
{