├── .gitignore
├── pics
├── pic1.PNG
├── pic2.PNG
├── pic3.PNG
├── pic4.PNG
├── pic5.PNG
├── pic6.PNG
├── pic7.PNG
└── pic6new.PNG
├── ExcelCake.Example
├── Template
│ ├── 复杂格式测试模板.xlsx
│ └── 复杂格式测试模板(新语法).xlsx
├── ExcelCake.Example.csproj
├── Entities
│ ├── AccountInfo.cs
│ ├── GradeReportInfo.cs
│ ├── ClassInfo.cs
│ └── UserInfo.cs
└── Program.cs
├── ExcelCake.Test
├── UnitTest1.cs
└── ExcelCake.Test.csproj
├── ExcelCake
├── Intrusive
│ ├── ExcelBase.cs
│ ├── ImportStyle.cs
│ ├── Attribute
│ │ ├── ExportMergeAttribute.cs
│ │ ├── ExportAttribute.cs
│ │ ├── ImportEntityAttribute.cs
│ │ ├── ImportAttribute.cs
│ │ └── ExportEntityAttribute.cs
│ ├── ImportColumn.cs
│ ├── ExportStyle.cs
│ ├── ExportColumn.cs
│ ├── ImportExcelSetting.cs
│ ├── ExportExcelSetting.cs
│ ├── Extension
│ │ ├── ImportExtension.cs
│ │ └── ExportExtension.cs
│ ├── ExcelHelper.cs
│ └── Enum
│ │ └── EnumColor.cs
├── ExcelCake.csproj
├── ImportFormatException.cs
├── NoIntrusive
│ ├── TemplateSetting
│ │ ├── TemplateRange.cs
│ │ ├── TemplateSettingRange.cs
│ │ ├── TemplateSettingField.cs
│ │ ├── TemplateSettingRangeGrid.cs
│ │ ├── TemplateSettingRangeFree.cs
│ │ ├── TemplateSettingSheet.cs
│ │ └── TemplateSettingRangeChart.cs
│ ├── TemplateSettingRange.cs
│ ├── DataObject.cs
│ ├── TemplateSettingSheet.cs
│ └── ExcelTemplate.cs
└── ExcelCommon.cs
├── ExcelCake.sln
├── LICENSE
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | packages
2 | bin
3 | obj
4 | .vs
5 | *.docx
6 | *.doc
--------------------------------------------------------------------------------
/pics/pic1.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/winstonwxj/ExcelCake/HEAD/pics/pic1.PNG
--------------------------------------------------------------------------------
/pics/pic2.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/winstonwxj/ExcelCake/HEAD/pics/pic2.PNG
--------------------------------------------------------------------------------
/pics/pic3.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/winstonwxj/ExcelCake/HEAD/pics/pic3.PNG
--------------------------------------------------------------------------------
/pics/pic4.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/winstonwxj/ExcelCake/HEAD/pics/pic4.PNG
--------------------------------------------------------------------------------
/pics/pic5.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/winstonwxj/ExcelCake/HEAD/pics/pic5.PNG
--------------------------------------------------------------------------------
/pics/pic6.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/winstonwxj/ExcelCake/HEAD/pics/pic6.PNG
--------------------------------------------------------------------------------
/pics/pic7.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/winstonwxj/ExcelCake/HEAD/pics/pic7.PNG
--------------------------------------------------------------------------------
/pics/pic6new.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/winstonwxj/ExcelCake/HEAD/pics/pic6new.PNG
--------------------------------------------------------------------------------
/ExcelCake.Example/Template/复杂格式测试模板.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/winstonwxj/ExcelCake/HEAD/ExcelCake.Example/Template/复杂格式测试模板.xlsx
--------------------------------------------------------------------------------
/ExcelCake.Example/Template/复杂格式测试模板(新语法).xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/winstonwxj/ExcelCake/HEAD/ExcelCake.Example/Template/复杂格式测试模板(新语法).xlsx
--------------------------------------------------------------------------------
/ExcelCake.Test/UnitTest1.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.VisualStudio.TestTools.UnitTesting;
2 |
3 | namespace ExcelCake.Test
4 | {
5 | [TestClass]
6 | public class UnitTest1
7 | {
8 | [TestMethod]
9 | public void TestMethod1()
10 | {
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ExcelCake/Intrusive/ExcelBase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace ExcelCake.Intrusive
7 | {
8 | public abstract class ExcelBase
9 | {
10 | public string ExcelName { set; get; }
11 | public string SheetName { set; get; }
12 | public int RowIndex { set; get; }
13 | public int ColumnIndex { set; get; }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/ExcelCake/ExcelCake.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ExcelCake/Intrusive/ImportStyle.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace ExcelCake.Intrusive
7 | {
8 | public class ImportStyle
9 | {
10 | ///
11 | ///
12 | ///
13 | public int TitleRowIndex { set; get; }
14 |
15 | ///
16 | ///
17 | ///
18 | public int HeadRowIndex { set; get; }
19 |
20 | ///
21 | ///
22 | ///
23 | public int DataRowIndex { set; get; }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/ExcelCake.Example/ExcelCake.Example.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp3.1
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | Always
15 |
16 |
17 | Always
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/ExcelCake.Test/ExcelCake.Test.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 |
6 | false
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/ExcelCake.Example/Entities/AccountInfo.cs:
--------------------------------------------------------------------------------
1 | using ExcelCake.Intrusive;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 |
7 | namespace ExcelCake.Example
8 | {
9 | [ExportEntity("账号信息")]
10 | public class AccountInfo:ExcelBase
11 | {
12 | [Export("编号", 1)]
13 | public int ID { set; get; }
14 |
15 | [Export("昵称", 2)]
16 | public string Nickname { set; get; }
17 |
18 | [Export("密码", 3)]
19 | public string Password { set; get; }
20 |
21 | [Export("旧密码", 4)]
22 | public string OldPassword { set; get; }
23 |
24 | [Export("状态", 5)]
25 | public int AccountStatus { set; get; }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/ExcelCake/ImportFormatException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Web;
5 |
6 | namespace ExcelCake
7 | {
8 | [Serializable]
9 | public class ImportFormatException: ApplicationException
10 | {
11 | private string[] _Messages;
12 |
13 | public string[] Messages
14 | {
15 | get
16 | {
17 | return _Messages;
18 | }
19 | }
20 |
21 | public ImportFormatException()
22 | {
23 | _Messages = new string[0];
24 | }
25 |
26 | public ImportFormatException(params string[] messages)
27 | {
28 | _Messages = messages;
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/ExcelCake/NoIntrusive/TemplateSetting/TemplateRange.cs:
--------------------------------------------------------------------------------
1 | using OfficeOpenXml;
2 | using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Text;
7 |
8 | namespace ExcelCake.NoIntrusive
9 | {
10 | [Serializable]
11 | internal abstract class TemplateSettingBase
12 | {
13 | internal string Content { set; get; }
14 |
15 | ///
16 | /// 配置所在单元格
17 | ///
18 | internal ExcelRangeBase CurrentCell { set; get; }
19 |
20 | ///
21 | /// 作用范围
22 | ///
23 | internal ExcelRangeBase ScopeRange { set; get; }
24 |
25 | protected abstract void AnalyseSetting();
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/ExcelCake/NoIntrusive/TemplateSettingRange.cs:
--------------------------------------------------------------------------------
1 | using OfficeOpenXml;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 |
7 | namespace ExcelCake.NoIntrusive
8 | {
9 | internal class TemplateSettingRange
10 | {
11 | public string Type { set; get; }
12 | public string DataSource { set; get; }
13 | //public string Address { set; get; }
14 | public string AddressLeftTop { set; get; }
15 | public string AddressRightBottom { set; get; }
16 | public string Field { set; get; }
17 | public string SettingString { set; get; }
18 | public ExcelRangeBase CurrentCell { set; get; }
19 | public int FromRow { set; get; }
20 | public int FromCol { set; get; }
21 | public int ToRow { set; get; }
22 | public int ToCol { set; get; }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/ExcelCake/Intrusive/Attribute/ExportMergeAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace ExcelCake.Intrusive
7 | {
8 | ///
9 | /// 导出列合并特性
10 | ///
11 | [AttributeUsage(AttributeTargets.Property)]
12 | public class ExportMergeAttribute: Attribute
13 | {
14 | private string _MergeText { get; set; }
15 |
16 | ///
17 | /// 合并后文本
18 | ///
19 | public string MergeText
20 | {
21 | get
22 | {
23 | return _MergeText;
24 | }
25 | set
26 | {
27 | _MergeText = value;
28 | }
29 | }
30 |
31 | public ExportMergeAttribute(string mergeText)
32 | {
33 | _MergeText = mergeText ?? "";
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/ExcelCake/NoIntrusive/TemplateSetting/TemplateSettingRange.cs:
--------------------------------------------------------------------------------
1 | using OfficeOpenXml;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 |
7 | namespace ExcelCake.NoIntrusive
8 | {
9 | [Serializable]
10 | internal abstract class TemplateSettingRange: TemplateSettingBase
11 | {
12 | internal List Fields { get; set; }
13 |
14 | internal string DataSource { set; get; }
15 | //public string Address { set; get; }
16 | internal string AddressLeftTop { set; get; }
17 | internal string AddressRightBottom { set; get; }
18 |
19 | internal int FromRow { set; get; }
20 | internal int FromCol { set; get; }
21 | internal int ToRow { set; get; }
22 | internal int ToCol { set; get; }
23 |
24 | internal abstract void Draw(ExcelWorksheet workSheet, ExcelObject dataSource);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/ExcelCake.Example/Entities/GradeReportInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace ExcelCake.Example
8 | {
9 | public class GradeReportInfo
10 | {
11 | public string ReportTitle { set; get; }
12 | ///
13 | /// 各班级各科目及格人数列表
14 | ///
15 | public List List1 { set; get; }
16 | ///
17 | /// 各班级各科目平均成绩
18 | ///
19 | public List List2 { set; get; }
20 | ///
21 | /// 各班级总分情况
22 | ///
23 | public List List3 { set; get; }
24 |
25 | public GradeReportInfo()
26 | {
27 | List1 = new List();
28 | List2 = new List();
29 | List3 = new List();
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/ExcelCake.Example/Entities/ClassInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace ExcelCake.Example
8 | {
9 | public class ClassInfo
10 | {
11 | public string ClassName { set; get; }
12 | public int PassCountSubject1 { set; get; }
13 | public int PassCountSubject2 { set; get; }
14 | public int PassCountSubject3 { set; get; }
15 | public int PassCountSubject4 { set; get; }
16 | public int PassCountSubject5 { set; get; }
17 |
18 | public double ScoreAvgSubject1 { set; get; }
19 | public double ScoreAvgSubject2 { set; get; }
20 | public double ScoreAvgSubject3 { set; get; }
21 | public double ScoreAvgSubject4 { set; get; }
22 | public double ScoreAvgSubject5 { set; get; }
23 |
24 | public double ScoreTotalMax { set; get; }
25 | public double ScoreTotalAvg { set; get; }
26 | public double ScoreTotalPassRate { set; get; }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/ExcelCake.Example/Entities/UserInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using ExcelCake.Intrusive;
8 | using System.Drawing;
9 |
10 | namespace ExcelCake.Example
11 | {
12 | [ExportEntity(EnumColor.LightGray, "用户信息")]
13 | [ImportEntity(titleRowIndex:1,headRowIndex:2,dataRowIndex:4)]
14 | public class UserInfo: ExcelBase
15 | {
16 | [Export(name:"编号", index:1,prefix:"ID:")]
17 | [Import(name:"编号",prefix:"ID:")]
18 | public int ID { set; get; }
19 |
20 | [Export("姓名", 2)]
21 | [Import("姓名")]
22 | public string Name { set; get; }
23 |
24 | [Export("性别", 3)]
25 | [Import("性别")]
26 | public string Sex { set; get; }
27 |
28 | [Export(name:"年龄", index:4,suffix:"岁")]
29 | [Import(name:"年龄",suffix:"岁",dataVerReg: @"^[1-9]\d*$", isRegFailThrowException:false)]
30 | public int Age { set; get; }
31 |
32 | [ExportMerge("联系方式")]
33 | [Export("电子邮件", 5)]
34 | [Import("电子邮件")]
35 | public string Email { set; get; }
36 |
37 | [ExportMerge("联系方式")]
38 | [Export("手机", 6)]
39 | [Import("手机")]
40 | public string TelPhone { set; get; }
41 |
42 | public override string ToString()
43 | {
44 | return string.Format($"ID:{ID},Name:{Name},Sex:{Sex},Age:{Age},Email:{Email},TelPhone:{TelPhone}");
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/ExcelCake/Intrusive/ImportColumn.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 | using System.Text;
6 |
7 | namespace ExcelCake.Intrusive
8 | {
9 | public class ImportColumn
10 | {
11 | public string Text { set; get; }
12 | public string Name { set; get; }
13 | public int ColumnIndex { set; get; }
14 | public bool IsUseTempField { set; get; }
15 | public string TempField { set; get; }
16 | public string Prefix { set; get; }
17 | public string Suffix { set; get; }
18 | public string DataVerReg { set; get; }
19 | public bool IsRegFailThrowException { set; get; }
20 |
21 |
22 | public ImportColumn()
23 | {
24 | IsUseTempField = false;
25 | }
26 |
27 | public ImportColumn(PropertyInfo property)
28 | {
29 | if (property == null)
30 | {
31 | return;
32 | }
33 | var importAttrArry = property.GetCustomAttributes(typeof(ImportAttribute), true);
34 | if (importAttrArry != null && importAttrArry.Length > 0)
35 | {
36 | var import = ((ImportAttribute)importAttrArry[0]);
37 | Name = property.Name;
38 | Text = import.Name;
39 | IsUseTempField = import.IsUseTempField;
40 | TempField = import.TempField;
41 | Prefix = import.Prefix;
42 | Suffix = import.Suffix;
43 | DataVerReg = import.DataVerReg;
44 | IsRegFailThrowException = import.IsRegFailThrowException;
45 | }
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/ExcelCake/Intrusive/ExportStyle.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 | using System.Linq;
5 | using System.Text;
6 |
7 | namespace ExcelCake.Intrusive
8 | {
9 | public class ExportStyle
10 | {
11 | ///
12 | /// 标题背景颜色
13 | ///
14 | public Color TitleColor { set; get; }
15 |
16 | ///
17 | /// 标题文本
18 | ///
19 | public string Title { set; get; }
20 |
21 | ///
22 | /// 标题文本字号
23 | ///
24 | public int TitleFontSize { set; get; }
25 |
26 | ///
27 | /// 标题是否粗体
28 | ///
29 | public bool IsTitleBold { set; get; }
30 |
31 | ///
32 | /// 标题合并列数
33 | ///
34 | public int TitleColumnSpan { set; get; }
35 |
36 | ///
37 | /// 列头背景颜色
38 | ///
39 | public Color HeadColor { set; get; }
40 |
41 | ///
42 | /// 列头字号
43 | ///
44 | public int HeadFontSize { set; get; }
45 |
46 | ///
47 | /// 列头是否粗体
48 | ///
49 | public bool IsHeadBold { set; get; }
50 |
51 | ///
52 | /// 内容背景色
53 | ///
54 | public Color ContentColor { set; get; }
55 |
56 | ///
57 | /// 内容字号
58 | ///
59 | public int ContentFontSize { set; get; }
60 |
61 | ///
62 | /// 内容是否粗体
63 | ///
64 | public bool IsContentBold { set; get; }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/ExcelCake/Intrusive/ExportColumn.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 | using System.Text;
6 |
7 | namespace ExcelCake.Intrusive
8 | {
9 | public class ExportColumn
10 | {
11 | public string Text { set; get; }
12 | public string Value { set; get; }
13 | public int Index { set; get; }
14 | public string Prefix { set; get; }
15 | public string Suffix { set; get; }
16 | public string MergeText { set; get; }
17 |
18 | public ExportColumn()
19 | {
20 |
21 | }
22 |
23 | public ExportColumn(PropertyInfo property)
24 | {
25 | if (property == null)
26 | {
27 | return;
28 | }
29 | var exportAttrArry = property.GetCustomAttributes(typeof(ExportAttribute), true);
30 | if (exportAttrArry != null && exportAttrArry.Length > 0)
31 | {
32 | var export = ((ExportAttribute)exportAttrArry[0]);
33 | string displayName = property.Name;
34 | if (!string.IsNullOrEmpty(export.Name))
35 | {
36 | displayName = export.Name;
37 | }
38 | Text = displayName;
39 | Value = property.Name;
40 | Index = export.SortIndex;
41 | Prefix = export.Prefix;
42 | Suffix = export.Suffix;
43 | var mergeAttrArry = property.GetCustomAttributes(typeof(ExportMergeAttribute), true);
44 | if (mergeAttrArry != null && mergeAttrArry.Length > 0)
45 | {
46 | MergeText = ((ExportMergeAttribute)mergeAttrArry[0]).MergeText;
47 | }
48 | }
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/ExcelCake/Intrusive/ImportExcelSetting.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace ExcelCake.Intrusive
7 | {
8 | public class ImportExcelSetting
9 | {
10 | public List ImportColumns { set; get; }
11 | public ImportStyle ImportStyle { set; get; }
12 |
13 | private ImportExcelSetting()
14 | {
15 |
16 | }
17 |
18 | public ImportExcelSetting(Type type)
19 | {
20 | ImportStyle = new ImportStyle();
21 | ImportColumns = new List();
22 | if (type == null)
23 | {
24 | return;
25 | }
26 |
27 | #region 组织表头
28 | var classAttrArry = type.GetCustomAttributes(typeof(ImportEntityAttribute), true);
29 | if (classAttrArry == null || classAttrArry.Length == 0)
30 | {
31 | return;
32 | }
33 |
34 | var importEntity = (ImportEntityAttribute)classAttrArry[0];
35 |
36 | ImportStyle.TitleRowIndex = importEntity.TitleRowIndex;
37 | ImportStyle.HeadRowIndex = importEntity.HeadRowIndex;
38 | ImportStyle.DataRowIndex = importEntity.DataRowIndex;
39 |
40 | var properties = type.GetProperties();
41 |
42 | foreach (var proper in properties)
43 | {
44 | var importAttrArry = proper.GetCustomAttributes(typeof(ImportAttribute), true);
45 | if (importAttrArry != null && importAttrArry.Length > 0)
46 | {
47 | var column = new ImportColumn(proper);
48 | if (column != null)
49 | {
50 | ImportColumns.Add(column);
51 | }
52 | }
53 | }
54 | #endregion
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/ExcelCake/Intrusive/Attribute/ExportAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Web;
5 |
6 | namespace ExcelCake.Intrusive
7 | {
8 | ///
9 | /// 导出特性,标注导出的属性
10 | ///
11 | [AttributeUsage(AttributeTargets.Property)]
12 | public class ExportAttribute:Attribute
13 | {
14 | private string _Name;
15 | private int _SortIndex;
16 | private string _Prefix;
17 | private string _Suffix;
18 |
19 | ///
20 | /// 导出名称
21 | ///
22 | public string Name
23 | {
24 | get
25 | {
26 | return _Name;
27 | }
28 | }
29 |
30 | ///
31 | /// 导出排序索引
32 | ///
33 | public int SortIndex
34 | {
35 | get
36 | {
37 | return _SortIndex;
38 | }
39 | }
40 |
41 | ///
42 | /// 前缀
43 | ///
44 | public string Prefix
45 | {
46 | get
47 | {
48 | return _Prefix;
49 | }
50 | set
51 | {
52 | _Prefix = value;
53 | }
54 | }
55 |
56 | ///
57 | /// 后缀
58 | ///
59 | public string Suffix
60 | {
61 | get
62 | {
63 | return _Suffix;
64 | }
65 | set
66 | {
67 | _Suffix = value;
68 | }
69 | }
70 |
71 | //合并相同列(list中)
72 |
73 | //WrapMode(自动列宽,自动换行)
74 |
75 | //列宽
76 |
77 | private ExportAttribute(string prefix="",string suffix="")
78 | {
79 | _Prefix = prefix ?? "";
80 | _Suffix = suffix ?? "";
81 | }
82 |
83 | public ExportAttribute(string name,int index=0, string prefix = "", string suffix = "")
84 | {
85 | _Name = name ?? "" ;
86 | _SortIndex = index;
87 | _Prefix = prefix ?? "";
88 | _Suffix = suffix ?? "";
89 | }
90 | }
91 | }
--------------------------------------------------------------------------------
/ExcelCake.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.6.33723.286
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExcelCake.Example", "ExcelCake.Example\ExcelCake.Example.csproj", "{411E802C-5397-45F2-A2C5-3C558B9320AE}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "解决方案项", "解决方案项", "{C6A10CBF-67E6-4A82-9266-F5DD6FB16580}"
9 | EndProject
10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExcelCake.Test", "ExcelCake.Test\ExcelCake.Test.csproj", "{CC62F6CE-A9C4-4759-9314-1CEB3E957900}"
11 | EndProject
12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExcelCake", "ExcelCake\ExcelCake.csproj", "{EF08BCAB-BA35-4543-AD03-B85BB2B1ECA9}"
13 | EndProject
14 | Global
15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
16 | Debug|Any CPU = Debug|Any CPU
17 | Release|Any CPU = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
20 | {411E802C-5397-45F2-A2C5-3C558B9320AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {411E802C-5397-45F2-A2C5-3C558B9320AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {411E802C-5397-45F2-A2C5-3C558B9320AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {411E802C-5397-45F2-A2C5-3C558B9320AE}.Release|Any CPU.Build.0 = Release|Any CPU
24 | {CC62F6CE-A9C4-4759-9314-1CEB3E957900}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
25 | {CC62F6CE-A9C4-4759-9314-1CEB3E957900}.Debug|Any CPU.Build.0 = Debug|Any CPU
26 | {CC62F6CE-A9C4-4759-9314-1CEB3E957900}.Release|Any CPU.ActiveCfg = Release|Any CPU
27 | {CC62F6CE-A9C4-4759-9314-1CEB3E957900}.Release|Any CPU.Build.0 = Release|Any CPU
28 | {EF08BCAB-BA35-4543-AD03-B85BB2B1ECA9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
29 | {EF08BCAB-BA35-4543-AD03-B85BB2B1ECA9}.Debug|Any CPU.Build.0 = Debug|Any CPU
30 | {EF08BCAB-BA35-4543-AD03-B85BB2B1ECA9}.Release|Any CPU.ActiveCfg = Release|Any CPU
31 | {EF08BCAB-BA35-4543-AD03-B85BB2B1ECA9}.Release|Any CPU.Build.0 = Release|Any CPU
32 | EndGlobalSection
33 | GlobalSection(SolutionProperties) = preSolution
34 | HideSolutionNode = FALSE
35 | EndGlobalSection
36 | GlobalSection(ExtensibilityGlobals) = postSolution
37 | SolutionGuid = {69687E7A-2532-4DA0-BCA0-F8A1BD1B07B7}
38 | EndGlobalSection
39 | EndGlobal
40 |
--------------------------------------------------------------------------------
/ExcelCake/Intrusive/Attribute/ImportEntityAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace ExcelCake.Intrusive
7 | {
8 | ///
9 | /// 导入特性,标注类的导入信息
10 | ///
11 | [AttributeUsage(AttributeTargets.Class)]
12 | public class ImportEntityAttribute: Attribute
13 | {
14 | private int _TitleRowIndex;
15 | private int _HeadRowIndex;
16 | private int _DataRowIndex;
17 |
18 | ///
19 | /// 标题行Index
20 | ///
21 | public int TitleRowIndex
22 | {
23 | get
24 | {
25 | return _TitleRowIndex;
26 | }
27 | set
28 | {
29 | _TitleRowIndex = value;
30 | }
31 | }
32 |
33 | ///
34 | /// 列头行Index
35 | ///
36 | public int HeadRowIndex
37 | {
38 | get
39 | {
40 | return _HeadRowIndex;
41 | }
42 | set
43 | {
44 | _HeadRowIndex = value;
45 | }
46 | }
47 |
48 | ///
49 | /// 数据行Index
50 | ///
51 | public int DataRowIndex
52 | {
53 | get
54 | {
55 | return _DataRowIndex;
56 | }
57 | set
58 | {
59 | _DataRowIndex = value;
60 | }
61 | }
62 |
63 | public ImportEntityAttribute()
64 | {
65 | _TitleRowIndex = 0;
66 | _HeadRowIndex = 1;
67 | _DataRowIndex = 2;
68 | }
69 |
70 | public ImportEntityAttribute(int headRowIndex, int dataRowIndex)
71 | {
72 | _TitleRowIndex = 0;
73 | _HeadRowIndex = headRowIndex < 1 ? 1 : headRowIndex;
74 | _DataRowIndex = dataRowIndex < 2 ? 2 : dataRowIndex;
75 | }
76 |
77 | public ImportEntityAttribute(int titleRowIndex,int headRowIndex,int dataRowIndex)
78 | {
79 | _TitleRowIndex = titleRowIndex < 0 ? 0 : titleRowIndex;
80 | _HeadRowIndex = headRowIndex < 1 ? 1 : headRowIndex;
81 | _DataRowIndex = dataRowIndex < 2 ? 2 : dataRowIndex;
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/ExcelCake/NoIntrusive/TemplateSetting/TemplateSettingField.cs:
--------------------------------------------------------------------------------
1 | using OfficeOpenXml;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Xml;
7 |
8 | namespace ExcelCake.NoIntrusive
9 | {
10 | [Serializable]
11 | internal class TemplateSettingField : TemplateSettingBase
12 | {
13 | public string Field { set; get; }
14 |
15 | private TemplateSettingField()
16 | {
17 |
18 | }
19 |
20 | internal static TemplateSettingField Create(ExcelRangeBase cell)
21 | {
22 | var entity = new TemplateSettingField();
23 | entity.CurrentCell = cell;
24 | entity.Content = cell.Value?.ToString() ?? "";
25 | entity.AnalyseSetting();
26 | return entity;
27 | }
28 |
29 | protected override void AnalyseSetting()
30 | {
31 | var cellValue = this.Content;
32 |
33 | var arry = cellValue.Split(new char[2] { '{', '}' }, StringSplitOptions.RemoveEmptyEntries);
34 | if (arry.Length == 0)
35 | {
36 | return;
37 | }
38 | foreach (var item in arry)
39 | {
40 | if (item.IndexOf(":") > -1 && item.IndexOf(";") > -1)
41 | {
42 | var settingItemArry = item.Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries);
43 | if (settingItemArry.Length == 0)
44 | {
45 | continue;
46 | }
47 |
48 | foreach (var arryItem in settingItemArry)
49 | {
50 | var settingItem = arryItem.Split(':');
51 | if (settingItem.Length < 2)
52 | {
53 | continue;
54 | }
55 | var key = settingItem[0];
56 | var value = settingItem[1];
57 | if (string.IsNullOrEmpty(key))
58 | {
59 | continue;
60 | }
61 |
62 | switch (key.ToUpper())
63 | {
64 | case "FIELD":
65 | {
66 | this.Field = value.ToUpper();
67 | }
68 | break;
69 | }
70 | }
71 |
72 | }
73 | }
74 |
75 | this.ScopeRange = this.CurrentCell;
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/ExcelCake/NoIntrusive/TemplateSetting/TemplateSettingRangeGrid.cs:
--------------------------------------------------------------------------------
1 | using OfficeOpenXml;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 |
7 | namespace ExcelCake.NoIntrusive
8 | {
9 | [Serializable]
10 | internal class TemplateSettingRangeGrid : TemplateSettingRange
11 | {
12 | public List UnderGrid { get; set; }
13 |
14 | private TemplateSettingRangeGrid()
15 | {
16 |
17 | }
18 |
19 | internal static TemplateSettingRangeGrid Create(ExcelRangeBase cell)
20 | {
21 | var entity = new TemplateSettingRangeGrid();
22 | entity.Fields = new List();
23 | entity.UnderGrid = new List();
24 | entity.Content = cell.Value?.ToString() ?? "";
25 | entity.CurrentCell = cell;
26 | entity.AnalyseSetting();
27 | return entity;
28 | }
29 |
30 | protected override void AnalyseSetting()
31 | {
32 | var cellValue = this.Content;
33 | var arry = cellValue.Split(new char[2] { '{', '}' }, StringSplitOptions.RemoveEmptyEntries);
34 | if (arry.Length == 0)
35 | {
36 | return;
37 | }
38 | foreach (var item in arry)
39 | {
40 | if (item.IndexOf(":") > -1 && item.IndexOf(";") > -1)
41 | {
42 | var settingItemArry = item.Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries);
43 | if (settingItemArry.Length == 0)
44 | {
45 | continue;
46 | }
47 |
48 | foreach (var arryItem in settingItemArry)
49 | {
50 | var settingItem = arryItem.Split(':');
51 | if (settingItem.Length < 2)
52 | {
53 | continue;
54 | }
55 | var key = settingItem[0];
56 | var value = settingItem[1];
57 | if (string.IsNullOrEmpty(key))
58 | {
59 | continue;
60 | }
61 |
62 | switch (key.ToUpper())
63 | {
64 | case "DATASOURCE": { this.DataSource = value.ToUpper(); } break;
65 | case "ADDRESSLEFTTOP": { this.AddressLeftTop = value.ToUpper(); } break;
66 | case "ADDRESSRIGHTBOTTOM": { this.AddressRightBottom = value.ToUpper(); } break;
67 | }
68 | }
69 | }
70 |
71 | ExcelCommon.CalcRowCol(this.AddressLeftTop, out int fromRow, out int fromCol);
72 | ExcelCommon.CalcRowCol(this.AddressRightBottom, out int toRow, out int toCol);
73 | this.FromRow = fromRow;
74 | this.FromCol = fromCol;
75 | this.ToRow = toRow;
76 | this.ToCol = toCol;
77 | this.ScopeRange = this.CurrentCell.Worksheet.Cells[this.FromRow, this.FromCol, this.ToRow, this.ToCol];
78 | }
79 | }
80 |
81 | internal override void Draw(ExcelWorksheet workSheet, ExcelObject dataSource)
82 | {
83 | throw new NotImplementedException();
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/ExcelCake/Intrusive/ExportExcelSetting.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Drawing;
7 |
8 | namespace ExcelCake.Intrusive
9 | {
10 | public class ExportExcelSetting
11 | {
12 | public List ExportColumns { set; get; }
13 | public ExportStyle ExportStyle { set; get; }
14 | public List> MergeList { set; get; }
15 |
16 | private ExportExcelSetting()
17 | {
18 |
19 | }
20 |
21 | public ExportExcelSetting(Type type)
22 | {
23 | ExportStyle = new ExportStyle();
24 | ExportColumns = new List();
25 | MergeList = new List>();
26 | if (type == null)
27 | {
28 | return;
29 | }
30 |
31 | #region 组织表头
32 | var classAttrArry = type.GetCustomAttributes(typeof(ExportEntityAttribute), true);
33 | if (classAttrArry == null || classAttrArry.Length == 0)
34 | {
35 | return;
36 | }
37 |
38 | var exportEntity = (ExportEntityAttribute)classAttrArry[0];
39 | ExportStyle.Title = exportEntity.Title;
40 | ExportStyle.HeadColor = ColorTranslator.FromHtml(exportEntity.HeadColor.ToString());
41 | ExportStyle.TitleColor = ColorTranslator.FromHtml(exportEntity.TitleColor.ToString());
42 | ExportStyle.TitleFontSize = exportEntity.TitleFontSize;
43 | ExportStyle.IsTitleBold = exportEntity.IsTitleBold;
44 | ExportStyle.TitleColumnSpan = exportEntity.TitleColumnSpan;
45 | ExportStyle.HeadFontSize = exportEntity.HeadFontSize;
46 | ExportStyle.IsHeadBold = exportEntity.IsHeadBold;
47 | ExportStyle.ContentColor = ColorTranslator.FromHtml(exportEntity.ContentColor.ToString());
48 | ExportStyle.ContentFontSize = exportEntity.ContentFontSize;
49 | ExportStyle.IsContentBold = exportEntity.IsContentBold;
50 | var properties = type.GetProperties();
51 |
52 | foreach (var proper in properties)
53 | {
54 | var exportAttrArry = proper.GetCustomAttributes(typeof(ExportAttribute), true);
55 | if (exportAttrArry != null && exportAttrArry.Length > 0)
56 | {
57 | var column = new ExportColumn(proper);
58 | if (column != null)
59 | {
60 | ExportColumns.Add(column);
61 | }
62 | }
63 | }
64 | #endregion
65 |
66 | #region 排序
67 | //ExportColumns.Sort((a, b) => a.Index.CompareTo(b.Index));
68 | var groupTemp = ExportColumns.GroupBy(o => o.MergeText);
69 | ExportColumns = new List();
70 | foreach(var item in groupTemp)
71 | {
72 | var mergeList = item.ToList();
73 | if (mergeList.Count == 1)
74 | {
75 | mergeList.First().MergeText = "";
76 | }
77 | else
78 | {
79 | mergeList.Sort((a, b) => a.Index.CompareTo(b.Index));
80 | MergeList.Add(new KeyValuePair(item.Key, item.Count()));
81 | }
82 |
83 | ExportColumns.AddRange(mergeList);
84 | }
85 | #endregion
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/ExcelCake/Intrusive/Attribute/ImportAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace ExcelCake.Intrusive
7 | {
8 | ///
9 | /// 导入特性,标注导入的属性
10 | ///
11 | [AttributeUsage(AttributeTargets.Property)]
12 | public class ImportAttribute: Attribute
13 | {
14 | private string _Name;
15 | private bool _IsUseTempField;
16 | private string _TempField;
17 | private string _Prefix;
18 | private string _Suffix;
19 | private string _DataVerReg;
20 | private bool _IsRegFailThrowException;
21 |
22 | ///
23 | /// 导入名称
24 | ///
25 | public string Name
26 | {
27 | get
28 | {
29 | return _Name;
30 | }
31 | }
32 |
33 | ///
34 | /// 是否使用临时字段
35 | ///
36 | public bool IsUseTempField
37 | {
38 | get
39 | {
40 | return _IsUseTempField;
41 | }
42 | set
43 | {
44 | _IsUseTempField = value;
45 | }
46 | }
47 |
48 | ///
49 | /// 临时字段
50 | ///
51 | public string TempField
52 | {
53 | get
54 | {
55 | return _TempField;
56 | }
57 | set
58 | {
59 | _TempField = value;
60 | }
61 | }
62 |
63 | ///
64 | /// 前缀
65 | ///
66 | public string Prefix
67 | {
68 | get
69 | {
70 | return _Prefix;
71 | }
72 | set
73 | {
74 | _Prefix = value;
75 | }
76 | }
77 |
78 | ///
79 | /// 后缀
80 | ///
81 | public string Suffix
82 | {
83 | get
84 | {
85 | return _Suffix;
86 | }
87 | set
88 | {
89 | _Suffix = value;
90 | }
91 | }
92 |
93 | ///
94 | /// 数据校验正则
95 | ///
96 | public string DataVerReg
97 | {
98 | get
99 | {
100 | return _DataVerReg;
101 | }
102 | set
103 | {
104 | _DataVerReg = value;
105 | }
106 | }
107 |
108 | ///
109 | /// 正则验证失败是否抛出异常
110 | ///
111 | public bool IsRegFailThrowException
112 | {
113 | get
114 | {
115 | return _IsRegFailThrowException;
116 | }
117 | set
118 | {
119 | _IsRegFailThrowException = value;
120 | }
121 | }
122 |
123 | //数据校验
124 |
125 | private ImportAttribute()
126 | {
127 | _IsUseTempField = false;
128 | }
129 |
130 | public ImportAttribute(string name, string dataVerReg = "", bool isRegFailThrowException = false,string prefix="",string suffix="")
131 | {
132 | _Name = name??"";
133 | _IsUseTempField = false;
134 | _DataVerReg = dataVerReg??"";
135 | _IsRegFailThrowException = isRegFailThrowException;
136 | _Prefix = prefix??"";
137 | _Suffix = suffix ?? "";
138 | }
139 |
140 | public ImportAttribute(string name,bool isUseTempField, string tempField, string prefix = "", string suffix = "")
141 | {
142 | _Name = name??"";
143 | _IsUseTempField = isUseTempField;
144 | _TempField = tempField??"";
145 | _Prefix = prefix ?? "";
146 | _Suffix = suffix ?? "";
147 | }
148 | }
149 | }
150 |
--------------------------------------------------------------------------------
/ExcelCake/NoIntrusive/TemplateSetting/TemplateSettingRangeFree.cs:
--------------------------------------------------------------------------------
1 | using OfficeOpenXml;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 |
7 | namespace ExcelCake.NoIntrusive
8 | {
9 | [Serializable]
10 | internal class TemplateSettingRangeFree : TemplateSettingRange
11 | {
12 | private TemplateSettingRangeFree()
13 | {
14 |
15 | }
16 |
17 | internal static TemplateSettingRangeFree Create(ExcelRangeBase cell)
18 | {
19 | var entity = new TemplateSettingRangeFree();
20 | entity.Fields = new List();
21 | entity.Content = cell.Value?.ToString() ?? "";
22 | entity.CurrentCell = cell;
23 | entity.AnalyseSetting();
24 | return entity;
25 | }
26 |
27 | protected override void AnalyseSetting()
28 | {
29 | var cellValue = this.Content;
30 | var arry = cellValue.Split(new char[2] { '{', '}' }, StringSplitOptions.RemoveEmptyEntries);
31 | if (arry.Length == 0)
32 | {
33 | return;
34 | }
35 | foreach (var item in arry)
36 | {
37 | if (item.IndexOf(":") > -1 && item.IndexOf(";") > -1)
38 | {
39 | var settingItemArry = item.Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries);
40 | if (settingItemArry.Length == 0)
41 | {
42 | continue;
43 | }
44 |
45 | foreach (var arryItem in settingItemArry)
46 | {
47 | var settingItem = arryItem.Split(':');
48 | if (settingItem.Length < 2)
49 | {
50 | continue;
51 | }
52 | var key = settingItem[0];
53 | var value = settingItem[1];
54 | if (string.IsNullOrEmpty(key))
55 | {
56 | continue;
57 | }
58 |
59 | switch (key.ToUpper())
60 | {
61 | case "DATASOURCE": { this.DataSource = value.ToUpper(); } break;
62 | case "ADDRESSLEFTTOP": { this.AddressLeftTop = value.ToUpper(); } break;
63 | case "ADDRESSRIGHTBOTTOM": { this.AddressRightBottom = value.ToUpper(); } break;
64 | }
65 | }
66 | }
67 | //var cellValueStr = cell.Value?.ToString() ?? "";
68 | //cell.Value = cellValueStr.Replace("{" + item + "}", "");
69 | }
70 |
71 | ExcelCommon.CalcRowCol(this.AddressLeftTop, out int fromRow, out int fromCol);
72 | ExcelCommon.CalcRowCol(this.AddressRightBottom, out int toRow, out int toCol);
73 | this.FromRow = fromRow;
74 | this.FromCol = fromCol;
75 | this.ToRow = toRow;
76 | this.ToCol = toCol;
77 | this.ScopeRange = this.CurrentCell.Worksheet.Cells[this.FromRow, this.FromCol, this.ToRow, this.ToCol];
78 | }
79 |
80 | internal override void Draw(ExcelWorksheet workSheet,ExcelObject dataSource)
81 | {
82 | if (string.IsNullOrEmpty(this.AddressLeftTop) || string.IsNullOrEmpty(this.AddressRightBottom))
83 | {
84 | return;
85 | }
86 | ExcelRange range = workSheet.Cells[this.AddressLeftTop + "," + this.AddressRightBottom];
87 |
88 | if (!dataSource.DataEntity.Keys.Contains(this.DataSource))
89 | {
90 | return;
91 | }
92 | var data = dataSource.DataEntity[this.DataSource];
93 |
94 | foreach (var field in Fields)
95 | {
96 | var fieldName = field.Field;
97 | var value = field.CurrentCell.Value?.ToString() ?? "";
98 | value = value.Replace(field.Content, "");
99 | object fieldData = null;
100 | if (data.Keys.Contains(field.Field))
101 | {
102 | fieldData = data[field.Field];
103 | }
104 | field.CurrentCell.Value = value + fieldData;
105 | }
106 | }
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/ExcelCake/NoIntrusive/DataObject.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Data;
5 | using System.Linq;
6 | using System.Reflection;
7 | using System.Text;
8 |
9 | namespace ExcelCake.NoIntrusive
10 | {
11 | public class ExcelObject
12 | {
13 | private static Dictionary> _PropertyInfo = new Dictionary>();
14 |
15 | public Dictionary> DataEntity { get; private set; }
16 | public Dictionary>> DataList { get; private set; }
17 |
18 | public ExcelObject(object dataSource)
19 | {
20 | AnalysisDataSource(dataSource);
21 | }
22 |
23 | public ExcelObject(DataSet dataSource)
24 | {
25 | AnalysisDataSource(dataSource);
26 | }
27 |
28 | ///
29 | ///
30 | ///
31 | ///
32 | private void AnalysisDataSource(object model)
33 | {
34 | DataEntity = new Dictionary>();
35 | DataEntity.Add(string.Empty, new Dictionary());
36 | DataList = new Dictionary>>();
37 |
38 | if (model == null)
39 | {
40 | return;
41 | }
42 |
43 | Type modelType = model.GetType();
44 | var tps = GetProperty(modelType);
45 |
46 | foreach (var pn in tps.Keys)
47 | {
48 | var tp = tps[pn];
49 | var tpv = tp.GetValue(model, null);
50 |
51 | if (tpv == null)
52 | {
53 | DataEntity[string.Empty].Add(pn, null);
54 | continue;
55 | }
56 | var tpt = tpv.GetType();
57 |
58 | if (tpt.Name.StartsWith("List") == true)
59 | {
60 | DataList.Add(pn.ToUpper(), new Dictionary>());
61 | var tpvs = tpv as IEnumerable;
62 | foreach (var tpvi in tpvs)
63 | {
64 | var tpp = GetProperty(tpvi.GetType());
65 | foreach (var tppp in tpp.Values)
66 | {
67 | if (DataList[pn.ToUpper()].ContainsKey(tppp.Name.ToUpper()) == false) DataList[pn.ToUpper()].Add(tppp.Name.ToUpper(), new List