mirror of
https://gitee.com/dotnetchina/MiniExcel.git
synced 2024-11-29 18:38:08 +08:00
[New] Add a merge attribute
This commit is contained in:
parent
694196f8b6
commit
4868c77ec8
Binary file not shown.
50
src/MiniExcel/Attributes/ExcelColumnAttribute.cs
Normal file
50
src/MiniExcel/Attributes/ExcelColumnAttribute.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user