Skip to content

Commit

Permalink
0.11.1
Browse files Browse the repository at this point in the history
- [New] Support Support ColumnIndex Attribute [#142](#142) & [#I3I3EB](https://gitee.com/dotnetchina/MiniExcel/issues/I3I3EB)
- [Bug] Fix issue #157 : Special conditions will get the wrong worksheet name
- [Update] issue #150 : SaveAs input IEnuerable<valuetype> should throw clear msg exception
  • Loading branch information
shps951023 committed Apr 9, 2021
1 parent 6b9e929 commit 5cba1ef
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 43 deletions.
5 changes: 5 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
## Release Notes

### 0.11.1
- [New] Support Support ColumnIndex Attribute [#142](https://github.com/shps951023/MiniExcel/issues/142) & [#I3I3EB](https://gitee.com/dotnetchina/MiniExcel/issues/I3I3EB)
- [Bug] Fix issue #157 : Special conditions will get the wrong worksheet name
- [Update] issue #150 : SaveAs input IEnuerable<valuetype> should throw clear msg exception

### 0.11.0
- [New] Added GetSheetNames method support multi-sheets Query
- [New] Query support by sheet name
Expand Down
2 changes: 2 additions & 0 deletions samples/csv/TestIssue142.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
MyProperty100,,MyProperty102,,CustomColumnName,,MyProperty103,MyProperty6,MyProperty2,,MyProperty3,MyProperty7,MyProperty1,MyProperty5,MyProperty4
MyProperty100,,MyProperty102,,CustomColumnName,,MyProperty103,MyProperty6,MyProperty2,,MyProperty3,MyProperty7,MyProperty1,MyProperty5,MyProperty4
Binary file added samples/xlsx/TestIssue142.xlsx
Binary file not shown.
3 changes: 2 additions & 1 deletion src/MiniExcel/Csv/CsvReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public IEnumerable<IDictionary<string, object>> Query(bool useHeaderRow, string
var cf = configuration == null ? CsvConfiguration.DefaultConfiguration : (CsvConfiguration)configuration;

var type = typeof(T);
var props = Helpers.GetSaveAsProperties(type);

Dictionary<int, PropertyInfo> idxProps = new Dictionary<int, PropertyInfo>();
using (var reader = cf.GetStreamReaderFunc(_stream))
{
Expand All @@ -79,6 +79,7 @@ public IEnumerable<IDictionary<string, object>> Query(bool useHeaderRow, string
{
row = reader.ReadLine();
read = row.Split(seperators, StringSplitOptions.None);
var props = Helpers.GetExcelCustomPropertyInfos(type, read);
var index = 0;
foreach (var v in read)
{
Expand Down
2 changes: 1 addition & 1 deletion src/MiniExcel/MiniExcelLibs.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<RepositoryUrl>https://github.com/shps951023/MiniExcel</RepositoryUrl>
<PackageIconUrl>https://raw.githubusercontent.com/shps951023/ImageHosting/master/img/2019-01-17.13.18.32-image.png</PackageIconUrl>
<TargetFrameworks>net461;netstandard2.0;net5.0</TargetFrameworks>
<Version>0.11.0</Version>
<Version>0.11.1</Version>
<PackageReleaseNotes>Please Check [Release Notes](https://github.com/shps951023/MiniExcel/tree/master/docs)</PackageReleaseNotes>
<RepositoryType>Github</RepositoryType>
</PropertyGroup>
Expand Down
15 changes: 13 additions & 2 deletions src/MiniExcel/OpenXml/ExcelOpenXmlSheetReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using static MiniExcelLibs.Utils.Helpers;

namespace MiniExcelLibs.OpenXml
{
Expand Down Expand Up @@ -47,7 +48,7 @@ public IEnumerable<IDictionary<string, object>> Query(bool UseHeaderRow, string
var s = _sheetRecords.SingleOrDefault(_ => _.Name == sheetName);
if (s == null)
throw new InvalidOperationException("Please check sheetName/Index is correct");
sheetEntry = sheets.Single(w => w.FullName == $"xl/{s.Path}" || w.FullName == $"/xl/{s.Path}" || w.FullName == s.Path || s.Path == $"/{w.FullName}" );
sheetEntry = sheets.Single(w => w.FullName == $"xl/{s.Path}" || w.FullName == $"/xl/{s.Path}" || w.FullName == s.Path || s.Path == $"/{w.FullName}");
}
else if (sheets.Count() > 1)
{
Expand Down Expand Up @@ -310,12 +311,22 @@ public IEnumerable<IDictionary<string, object>> Query(bool UseHeaderRow, string
public IEnumerable<T> Query<T>(string sheetName, IConfiguration configuration) where T : class, new()
{
var type = typeof(T);
var props = Helpers.GetExcelCustomPropertyInfos(type);

var first = true;
List<ExcelCustomPropertyInfo> props = null;
var headers = Query(false, sheetName, configuration).FirstOrDefault()?.Values?.Select(s=>s?.ToString())?.ToArray(); //TODO:need to optimize
foreach (var item in Query(true, sheetName, configuration))
{
if (first)
{
//TODO: alert don't duplicate column name
props = Helpers.GetExcelCustomPropertyInfos(type, headers);
first = false;
}
var v = new T();
foreach (var pInfo in props)
{
//TODO:don't need to check every time?
if (item.ContainsKey(pInfo.ExcelColumnName))
{
object newV = null;
Expand Down
31 changes: 19 additions & 12 deletions src/MiniExcel/Utils/Helpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,6 @@ internal static List<ExcelCustomPropertyInfo> GetSaveAsProperties(this Type type
if (props.Count == 0)
throw new InvalidOperationException($"{type.Name} un-ignore properties count can't be 0");

// TODO: complex case like mix with columnindex and columnname

// TODO: get header columns and index first


// https://github.com/shps951023/MiniExcel/issues/142
//TODO: need optimize performance
{
Expand Down Expand Up @@ -111,14 +106,8 @@ internal static List<ExcelCustomPropertyInfo> GetSaveAsProperties(this Type type
index++;
}
}

return newProps;
}





}

internal class ExcelCustomPropertyInfo
Expand All @@ -130,7 +119,7 @@ internal class ExcelCustomPropertyInfo
public bool Nullable { get; internal set; }
}

internal static List<ExcelCustomPropertyInfo> GetExcelCustomPropertyInfos(Type type)
internal static List<ExcelCustomPropertyInfo> GetExcelCustomPropertyInfos(Type type, string[] headers)
{
List<ExcelCustomPropertyInfo> props = GetExcelPropertyInfo(type, BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.Instance)
.Where(prop => prop.Property.IsSupportSetMethod() && !prop.Property.GetAttributeValue((ExcelIgnoreAttribute x) => x.ExcelIgnore))
Expand All @@ -139,6 +128,24 @@ internal static List<ExcelCustomPropertyInfo> GetExcelCustomPropertyInfos(Type t
if (props.Count == 0)
throw new InvalidOperationException($"{type.Name} un-ignore properties count can't be 0");

{
var withCustomIndexProps = props.Where(w => w.ExcelColumnIndex != null && w.ExcelColumnIndex > -1);
if (withCustomIndexProps.GroupBy(g => g.ExcelColumnIndex).Any(_ => _.Count() > 1))
throw new InvalidOperationException($"Duplicate column name");

foreach (var p in props)
{
if(p.ExcelColumnIndex != null)
{
if (p.ExcelColumnIndex >= headers.Length)
throw new ArgumentException($"ExcelColumnIndex {p.ExcelColumnIndex} over haeder max index {headers.Length}");
p.ExcelColumnName = headers[(int)p.ExcelColumnIndex];
if (p.ExcelColumnName == null)
throw new InvalidOperationException($"{p.Property.DeclaringType.Name} {p.Property.Name}'s ExcelColumnIndex {p.ExcelColumnIndex} can't find excel column name");
}
}
}

return props;
}

Expand Down
131 changes: 104 additions & 27 deletions tests/MiniExcelTests/MiniExcelIssueTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,36 +26,63 @@ public void Issue142()
{
{
var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid().ToString()}.xlsx");
MiniExcel.SaveAs(path, new Issue142VO[] { new Issue142VO { } });
MiniExcel.SaveAs(path, new Issue142VO[] { new Issue142VO { MyProperty1= "MyProperty1", MyProperty2= "MyProperty2", MyProperty3= "MyProperty3", MyProperty4= "MyProperty4", MyProperty5= "MyProperty5", MyProperty6= "MyProperty6", MyProperty7= "MyProperty7" } });

var rows = MiniExcel.Query(path).ToList();
{
var rows = MiniExcel.Query(path).ToList();

Assert.Equal("MyProperty4", rows[0].A);
Assert.Equal("CustomColumnName", rows[0].B); //note
Assert.Equal("MyProperty5", rows[0].C);
Assert.Equal("MyProperty2", rows[0].D);
Assert.Equal("MyProperty6", rows[0].E);
Assert.Equal(null, rows[0].F);
Assert.Equal("MyProperty3", rows[0].G);

Assert.Equal("MyProperty4", rows[0].A);
Assert.Equal("CustomColumnName", rows[0].B); //note
Assert.Equal("MyProperty5", rows[0].C);
Assert.Equal("MyProperty2", rows[0].D);
Assert.Equal("MyProperty6", rows[0].E);
Assert.Equal(null, rows[0].F);
Assert.Equal("MyProperty3", rows[0].G);
}

{
var rows = MiniExcel.Query<Issue142VO>(path).ToList();

Assert.Equal("MyProperty4", rows[0].A);
Assert.Equal("CustomColumnName", rows[0].B);
Assert.Equal("MyProperty5", rows[0].C);
Assert.Equal("MyProperty2", rows[0].D);
Assert.Equal("MyProperty6", rows[0].E);
Assert.Equal(null, rows[0].F);
Assert.Equal("MyProperty3", rows[0].G);

Assert.Equal(0, rows[1].A);
Assert.Equal(0, rows[1].B);
Assert.Equal(0, rows[1].C);
Assert.Equal(0, rows[1].D);
Assert.Equal(0, rows[1].E);
Assert.Equal(null, rows[1].F);
Assert.Equal(0, rows[1].G);

Assert.Equal("MyProperty4", rows[0].MyProperty4);
Assert.Equal("MyProperty1", rows[0].MyProperty1); //note
Assert.Equal("MyProperty5", rows[0].MyProperty5);
Assert.Equal("MyProperty2", rows[0].MyProperty2);
Assert.Equal("MyProperty6", rows[0].MyProperty6);
Assert.Null(rows[0].MyProperty7);
Assert.Equal("MyProperty3", rows[0].MyProperty3);
}

}

{
var path = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid().ToString()}.csv");
MiniExcel.SaveAs(path, new Issue142VO[] { new Issue142VO { } });

MiniExcel.SaveAs(path, new Issue142VO[] { new Issue142VO { MyProperty1 = "MyProperty1", MyProperty2 = "MyProperty2", MyProperty3 = "MyProperty3", MyProperty4 = "MyProperty4", MyProperty5 = "MyProperty5", MyProperty6 = "MyProperty6", MyProperty7 = "MyProperty7" } });
var expected = @"MyProperty4,CustomColumnName,MyProperty5,MyProperty2,MyProperty6,,MyProperty3
0,0,0,0,0,,0
MyProperty4,MyProperty1,MyProperty5,MyProperty2,MyProperty6,,MyProperty3
";
Assert.Equal(expected, File.ReadAllText(path));

{
var rows = MiniExcel.Query<Issue142VO>(path).ToList();


Assert.Equal("MyProperty4", rows[0].MyProperty4);
Assert.Equal("MyProperty1", rows[0].MyProperty1); //note
Assert.Equal("MyProperty5", rows[0].MyProperty5);
Assert.Equal("MyProperty2", rows[0].MyProperty2);
Assert.Equal("MyProperty6", rows[0].MyProperty6);
Assert.Null(rows[0].MyProperty7);
Assert.Equal("MyProperty3", rows[0].MyProperty3);
}
}

{
Expand All @@ -65,20 +92,58 @@ public void Issue142()
}
}

[Fact]
public void Issue142_Query()
{
{
var path = @"..\..\..\..\..\samples\xlsx\TestIssue142.xlsx";
Assert.Throws<InvalidOperationException>(() => MiniExcel.Query<Issue142VoExcelColumnNameNotFound>(path).ToList());
}

{
var path = @"..\..\..\..\..\samples\xlsx\TestIssue142.xlsx";
Assert.Throws<ArgumentException>(() => MiniExcel.Query<Issue142VoOverIndex>(path).ToList());
}

{
var path = @"..\..\..\..\..\samples\xlsx\TestIssue142.xlsx";
var rows = MiniExcel.Query<Issue142VO>(path).ToList();
Assert.Equal("CustomColumnName", rows[0].MyProperty1);
Assert.Null(rows[0].MyProperty7);
Assert.Equal("MyProperty2", rows[0].MyProperty2);
Assert.Equal("MyProperty103", rows[0].MyProperty3);
Assert.Equal("MyProperty100", rows[0].MyProperty4);
Assert.Equal("MyProperty102", rows[0].MyProperty5);
Assert.Equal("MyProperty6", rows[0].MyProperty6);
}

{
var path = @"..\..\..\..\..\samples\csv\TestIssue142.csv";
var rows = MiniExcel.Query<Issue142VO>(path).ToList();
Assert.Equal("CustomColumnName", rows[0].MyProperty1);
Assert.Null(rows[0].MyProperty7);
Assert.Equal("MyProperty2", rows[0].MyProperty2);
Assert.Equal("MyProperty103", rows[0].MyProperty3);
Assert.Equal("MyProperty100", rows[0].MyProperty4);
Assert.Equal("MyProperty102", rows[0].MyProperty5);
Assert.Equal("MyProperty6", rows[0].MyProperty6);
}
}

public class Issue142VO
{
[ExcelColumnName("CustomColumnName")]
public int MyProperty1 { get; set; } //index = 1
public string MyProperty1 { get; set; } //index = 1
[ExcelIgnore]
public int MyProperty7 { get; set; } //index = null
public int MyProperty2 { get; set; } //index = 3
public string MyProperty7 { get; set; } //index = null
public string MyProperty2 { get; set; } //index = 3
[ExcelColumnIndex(6)]
public int MyProperty3 { get; set; } //index = 6
public string MyProperty3 { get; set; } //index = 6
[ExcelColumnIndex("A")] // equal column index 0
public int MyProperty4 { get; set; }
public string MyProperty4 { get; set; }
[ExcelColumnIndex(2)]
public int MyProperty5 { get; set; } //index = 2
public int MyProperty6 { get; set; } //index = 4
public string MyProperty5 { get; set; } //index = 2
public string MyProperty6 { get; set; } //index = 4
}

public class Issue142VoDuplicateColumnName
Expand All @@ -93,6 +158,18 @@ public class Issue142VoDuplicateColumnName
public int MyProperty4 { get; set; }
}

public class Issue142VoOverIndex
{
[ExcelColumnIndex("Z")]
public int MyProperty1 { get; set; }
}

public class Issue142VoExcelColumnNameNotFound
{
[ExcelColumnIndex("B")]
public int MyProperty1 { get; set; }
}

/// <summary>
/// https://github.com/shps951023/MiniExcel/issues/150
/// </summary>
Expand Down

0 comments on commit 5cba1ef

Please sign in to comment.