Skip to content

Commit c4894aa

Browse files
committed
Merge
2 parents 23353d0 + a5574ee commit c4894aa

16 files changed

+938
-158
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*************************************************************************************************
2+
Required Notice: Copyright (C) EPPlus Software AB.
3+
This software is licensed under PolyForm Noncommercial License 1.0.0
4+
and may only be used for noncommercial purposes
5+
https://polyformproject.org/licenses/noncommercial/1.0.0/
6+
7+
A commercial license to use this software can be purchased at https://epplussoftware.com
8+
*************************************************************************************************
9+
Date Author Change
10+
*************************************************************************************************
11+
7/11/2023 EPPlus Software AB EPPlus 7
12+
*************************************************************************************************/
13+
using System;
14+
using System.Collections.Generic;
15+
using System.Linq;
16+
using System.Text;
17+
18+
namespace OfficeOpenXml.Attributes
19+
{
20+
/// <summary>
21+
/// This attributes can only be used on properties that are of the type IDictionary&lt;string, string&gt;.
22+
/// Columns will be added based on the items in <see cref="EPPlusDictionaryColumnAttribute.ColumnHeaders"/>
23+
/// </summary>
24+
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field)]
25+
internal class EPPlusDictionaryColumnAttribute : Attribute
26+
{
27+
/// <summary>
28+
/// Order of the columns value, default value is 0
29+
/// </summary>
30+
public int Order
31+
{
32+
get;
33+
set;
34+
}
35+
36+
/// <summary>
37+
/// The values of this array will be used to generate columns (one column for each item).
38+
/// </summary>
39+
public string[] ColumnHeaders { get; set; }
40+
41+
/// <summary>
42+
/// Should be unique within all attributes. Will be used to retrieve the keys of the Dictionary
43+
/// that also will be used to create the columns for this property.
44+
/// </summary>
45+
public string KeyId { get; set; }
46+
}
47+
}

src/EPPlus/ExcelWorkbook.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1368,9 +1368,7 @@ private void SaveSharedStringHandler(ZipOutputStream stream, CompressionLevel co
13681368
SharedStringItem ssi = _sharedStrings[t];
13691369
if (ssi.isRichText)
13701370
{
1371-
cache.Append("<si>");
1372-
ConvertUtil.ExcelEncodeString(cache, t);
1373-
cache.Append("</si>");
1371+
cache.Append($"<si>{t}</si>");
13741372
}
13751373
else
13761374
{

src/EPPlus/FormulaParsing/Excel/Functions/Engineering/ConvertFunction.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ namespace OfficeOpenXml.FormulaParsing.Excel.Functions.Engineering
2121
[FunctionMetadata(
2222
Category = ExcelFunctionCategory.Engineering,
2323
EPPlusVersion = "5.1",
24-
Description = "Calculates the modified Bessel function Yn(x)")]
24+
Description = "Converts a number from one measurement system to another")]
2525
public class ConvertFunction : ExcelFunction
2626
{
2727
public override int ArgumentMinLength => 3;

src/EPPlus/LoadFunctions/ColumnInfo.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ public ColumnInfo()
3030

3131
public int SortOrder { get; set; }
3232

33+
public bool IsDictionaryProperty { get; set; }
34+
35+
public string DictinaryKey { get; set; }
36+
3337
public List<int> SortOrderLevels { get; set; }
3438
public int Index { get; set; }
3539

src/EPPlus/LoadFunctions/LoadFromCollection.cs

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,16 @@ public LoadFromCollection(ExcelRangeBase range, IEnumerable<T> items, LoadFromCo
4646
ShowTotal = tableAttr.ShowTotal;
4747
}
4848
var classSortOrderAttr = type.GetFirstAttributeOfType<EPPlusTableColumnSortOrderAttribute>();
49-
if(classSortOrderAttr != null && classSortOrderAttr.Properties != null && classSortOrderAttr.Properties.Length > 0)
49+
if (classSortOrderAttr != null && classSortOrderAttr.Properties != null && classSortOrderAttr.Properties.Length > 0)
5050
{
5151
SortOrderProperties = classSortOrderAttr.Properties.ToList();
52+
var scanner = new NestedColumnsSortorderScanner(type, parameters.BindingFlags);
53+
SortOrderProperties = scanner.GetSortOrder();
5254
}
5355
LoadFromCollectionColumns<T> cols;
5456
if (parameters.Members == null)
5557
{
56-
cols = new LoadFromCollectionColumns<T>(parameters.BindingFlags, SortOrderProperties);
58+
cols = new LoadFromCollectionColumns<T>(parameters, SortOrderProperties);
5759
var columns = cols.Setup();
5860
_columns = columns.ToArray();
5961
SetHiddenColumns();
@@ -64,7 +66,7 @@ public LoadFromCollection(ExcelRangeBase range, IEnumerable<T> items, LoadFromCo
6466
{
6567
throw (new ArgumentException("Parameter Members must have at least one property. Length is zero"));
6668
}
67-
cols = new LoadFromCollectionColumns<T>(parameters.BindingFlags, SortOrderProperties, parameters.Members);
69+
cols = new LoadFromCollectionColumns<T>(parameters, SortOrderProperties);
6870
var columns = cols.Setup();
6971
_columns = columns.ToArray();
7072
// the ValidateType method will throw an InvalidCastException
@@ -226,6 +228,18 @@ private void SetValuesAndFormulas(object[,] values, Dictionary<int, FormulaCell>
226228
{
227229
v = ((MethodInfo)member).Invoke(obj, null);
228230
}
231+
if (colInfo.IsDictionaryProperty)
232+
{
233+
var dict = v as Dictionary<string, object>;
234+
if(dict != null && dict.ContainsKey(colInfo.DictinaryKey))
235+
{
236+
v = dict[colInfo.DictinaryKey];
237+
}
238+
else
239+
{
240+
v = null;
241+
}
242+
}
229243

230244
#if (!NET35)
231245
if (v != null)
@@ -271,8 +285,9 @@ private object GetValueByPath(object obj, string path)
271285
{
272286
var members = path.Split('.');
273287
object o = obj;
274-
foreach(var member in members)
288+
for(var ix = 0; ix < members.Length; ix++)
275289
{
290+
var member = members[ix];
276291
if (o == null) return null;
277292
var memberInfos = o.GetType().GetMember(member);
278293
if(memberInfos == null || memberInfos.Length == 0)
@@ -296,6 +311,19 @@ private object GetValueByPath(object obj, string path)
296311
{
297312
throw new NotSupportedException("Invalid member: '" + memberInfo.Name + "', not supported member type '" + memberInfo.GetType().FullName + "'");
298313
}
314+
if(o is Dictionary<string, object> dict && ix < members.Length + 1)
315+
{
316+
var key = members[ix + 1];
317+
if(dict.ContainsKey(key))
318+
{
319+
o = dict[key];
320+
}
321+
else
322+
{
323+
o = null;
324+
}
325+
break;
326+
}
299327
}
300328
return o;
301329
}

0 commit comments

Comments
 (0)