-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPivotTableExportService.cs
More file actions
129 lines (108 loc) · 4.72 KB
/
Copy pathPivotTableExportService.cs
File metadata and controls
129 lines (108 loc) · 4.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
using DevExpress.Blazor.PivotTable;
using DevExpress.Spreadsheet;
namespace PivotTableExcelExport.Services;
public class PivotTableExportService {
public byte[] ExportToExcel<T>(IEnumerable<T> data, PivotTablePersistentLayout layout, PivotTableExportConfig? config = null) {
config ??= new PivotTableExportConfig();
using var workbook = new Workbook();
var dataSheet = workbook.Worksheets[0];
dataSheet.Name = "PivotTableData";
var properties = typeof(T).GetProperties();
for (int col = 0; col < properties.Length; col++) {
dataSheet.Cells[0, col].Value = properties[col].Name;
}
var dataList = data.ToList();
for (int row = 0; row < dataList.Count; row++) {
for (int col = 0; col < properties.Length; col++) {
var value = properties[col].GetValue(dataList[row]);
var cell = dataSheet.Cells[row + 1, col];
switch (value) {
case int intVal:
cell.Value = intVal;
break;
case DateTime dateVal:
cell.Value = dateVal;
cell.NumberFormat = "m/d/yyyy";
break;
case string strVal:
cell.Value = strVal;
break;
}
}
}
int lastRow = dataList.Count;
int lastCol = properties.Length - 1;
var sourceRange = dataSheet.Range.FromLTRB(0, 0, lastCol, lastRow);
var pivotSheet = workbook.Worksheets.Add("PivotTable");
workbook.Worksheets.ActiveWorksheet = pivotSheet;
var pivotTable = pivotSheet.PivotTables.Add(sourceRange, pivotSheet["A1"]);
pivotTable.BeginUpdate();
var layoutFields = layout.Fields
.Where(f => f.Area.HasValue && f.Visible != false)
.OrderBy(f => f.AreaIndex)
.ToList();
var addedColumnFields = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
foreach (var layoutField in layoutFields) {
var fieldName = layoutField.Field;
if (string.IsNullOrEmpty(fieldName))
continue;
var pivotField = FindPivotField(pivotTable, fieldName);
if (pivotField == null)
continue;
switch (layoutField.Area) {
case PivotTableArea.Row:
pivotTable.RowFields.Add(pivotField);
break;
case PivotTableArea.Column:
if (!addedColumnFields.Contains(fieldName)) {
pivotTable.ColumnFields.Add(pivotField);
addedColumnFields.Add(fieldName);
}
break;
case PivotTableArea.Data:
var dataField = pivotTable.DataFields.Add(pivotField);
if (config.DataFieldConfigs.TryGetValue(fieldName, out var dfConfig)) {
dataField.SummarizeValuesBy = dfConfig.SummaryFunction;
if (!string.IsNullOrEmpty(dfConfig.Caption))
dataField.Name = dfConfig.Caption;
}
break;
case PivotTableArea.Filter:
pivotTable.PageFields.Add(pivotField);
break;
}
}
pivotTable.Style = workbook.TableStyles[BuiltInPivotStyleId.PivotStyleMedium2];
pivotTable.EndUpdate();
foreach (var kvp in config.ColumnFieldGroupings) {
var pivotField = FindPivotField(pivotTable, kvp.Key);
if (pivotField != null) {
pivotField.GroupItems(kvp.Value.GroupBy);
}
}
using var stream = new MemoryStream();
workbook.SaveDocument(stream, DocumentFormat.Xlsx);
return stream.ToArray();
}
private static PivotField? FindPivotField(PivotTable pivotTable, string fieldName) {
for (int i = 0; i < pivotTable.Fields.Count; i++) {
if (string.Equals(pivotTable.Fields[i].Name, fieldName, StringComparison.OrdinalIgnoreCase))
return pivotTable.Fields[i];
}
return null;
}
}
public class DataFieldConfig
{
public PivotDataConsolidationFunction SummaryFunction { get; set; } = PivotDataConsolidationFunction.Sum;
public string? Caption { get; set; }
}
public class ColumnFieldGroupingConfig
{
public PivotFieldGroupByType GroupBy { get; set; }
}
public class PivotTableExportConfig
{
public Dictionary<string, DataFieldConfig> DataFieldConfigs { get; set; } = new();
public Dictionary<string, ColumnFieldGroupingConfig> ColumnFieldGroupings { get; set; } = new();
}