Skip to content

Commit 6a21e15

Browse files
Add readme (#1)
* add readme * Apply suggestions from code review Co-authored-by: Elena Khamliuk <80813840+khamlyuk@users.noreply.github.com> * Apply suggestion from @khamlyuk Co-authored-by: Elena Khamliuk <80813840+khamlyuk@users.noreply.github.com> * apply readme review changes --------- Co-authored-by: Elena Khamliuk <80813840+khamlyuk@users.noreply.github.com>
1 parent 1e7d3d3 commit 6a21e15

2 files changed

Lines changed: 221 additions & 0 deletions

File tree

README.md

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
# Blazor Pivot Table - Export Data to Excel Using Spreadsheet Document APIs
2+
3+
This example exports data from the [DevExpress Blazor Pivot Table](https://docs.devexpress.com/Blazor/405245/components/pivot-table) component to an Excel workbook. Once an export operation is complete, the application downloads the generated file.
4+
5+
> **Note**: This example uses the [DevExpress Office File API](https://docs.devexpress.com/Blazor/404576/components/office-file-api) - a standalone library that allows you to read/write documents, spreadsheets, presentations, and PDF files. The DevExpress Office File API is included in the following subscriptions: [DevExpress Office File API Subscription](https://www.devexpress.com/products/net/office-file-api/) or [DevExpress Universal Subscription](https://www.devexpress.com/subscriptions/universal.xml).
6+
7+
![DevExpress Blazor Pivot Table - Export Data to Excel](blazor-pivot-table-export-to-excel.png)
8+
9+
## Implementation Details
10+
11+
### Set Up Your Pivot Table
12+
13+
Add a [DevExpress Blazor Pivot Table](https://docs.devexpress.com/Blazor/405245/components/pivot-table) and populate it with data:
14+
15+
```Razor
16+
<DxPivotTable Data="@PivotTableData" @ref="pivotTable">
17+
<Fields>
18+
<DxPivotTableField Area="PivotTableArea.Row"
19+
Field="@nameof(SaleInfo.Region)"
20+
SortOrder="PivotTableSortOrder.Descending" />
21+
<DxPivotTableField Area="PivotTableArea.Row"
22+
Field="@nameof(SaleInfo.Country)" />
23+
<DxPivotTableField Area="PivotTableArea.Column"
24+
Field="@nameof(SaleInfo.Date)"
25+
GroupInterval="PivotTableGroupInterval.DateYear"
26+
Caption="Year" />
27+
<DxPivotTableField Area="PivotTableArea.Column"
28+
Field="@nameof(SaleInfo.Date)"
29+
GroupInterval="PivotTableGroupInterval.DateQuarter"
30+
Caption="Quarter" />
31+
<DxPivotTableField Area="PivotTableArea.Data"
32+
Field="@nameof(SaleInfo.Amount)"
33+
SummaryType="PivotTableSummaryType.Sum"
34+
CellFormat="C0" />
35+
<DxPivotTableField Area="PivotTableArea.Data"
36+
Field="@nameof(SaleInfo.OrderId)"
37+
SummaryType="PivotTableSummaryType.Count"
38+
Caption="Count" />
39+
</Fields>
40+
</DxPivotTable>
41+
42+
@code {
43+
IPivotTable pivotTable { get; set; } = null!;
44+
SaleInfo[]? PivotTableData;
45+
46+
protected override void OnInitialized() {
47+
// Assign data to PivotTableData here
48+
}
49+
}
50+
```
51+
52+
### Add an Export Button
53+
54+
Add a [DevExpress Blazor Button](https://docs.devexpress.com/Blazor/405052/components/utility-controls/button) to the page. Do the following in the button Click event handler:
55+
56+
1. Obtain the dataset bound to our Blazor Pivot Table.
57+
1. Call the [DxPivotTable.SaveLayout](https://docs.devexpress.com/Blazor/DevExpress.Blazor.PivotTable.DxPivotTable.SaveLayout) method to retrieve persisted layout information (a [PivotTablePersistentLayout](https://docs.devexpress.com/Blazor/DevExpress.Blazor.PivotTable.PivotTablePersistentLayout) object).
58+
1. Create a `PivotTableExportConfig` object to store custom export options.
59+
1. Pass dataset, layout information, and export options as parameters to the `ExportToExcel` method.
60+
1. Once the export engine returns a generated Excel document, download it to the user machine.
61+
62+
```Razor
63+
<DxButton Text="Export to Excel" Click="OnExportClick" />
64+
65+
@code {
66+
async Task OnExportClick() {
67+
var layout = pivotTable.SaveLayout();
68+
var exportConfig = new Services.PivotTableExportConfig {
69+
// Changes the `OrderId` field summary type to `Count`
70+
DataFieldConfigs = new() {
71+
["OrderId"] = new Services.DataFieldConfig {
72+
SummaryFunction = DevExpress.Spreadsheet.PivotDataConsolidationFunction.Count,
73+
Caption = "Count"
74+
}
75+
},
76+
// Groups the `Date` column by years and quarters
77+
ColumnFieldGroupings = new() {
78+
["Date"] = new Services.ColumnFieldGroupingConfig {
79+
GroupBy = DevExpress.Spreadsheet.PivotFieldGroupByType.Years | DevExpress.Spreadsheet.PivotFieldGroupByType.Quarters
80+
}
81+
}
82+
};
83+
var fileBytes = ExportService.ExportToExcel(PivotTableData, layout, exportConfig);
84+
85+
using var stream = new MemoryStream(fileBytes);
86+
using var streamRef = new DotNetStreamReference(stream);
87+
await JS.InvokeVoidAsync("downloadFileFromStream", "PivotTableExport.xlsx", streamRef);
88+
}
89+
}
90+
```
91+
92+
### Implement an Export Engine
93+
94+
To export Blazor Pivot Table data to Excel, you must:
95+
96+
1. Create a [Workbook](https://docs.devexpress.com/OfficeFileAPI/DevExpress.Spreadsheet.Workbook) instance and access the first worksheet.
97+
98+
```cs
99+
using var workbook = new Workbook();
100+
var dataSheet = workbook.Worksheets[0];
101+
```
102+
1. Iterate through dataset properties and create corresponding header cells in the worksheet.
103+
104+
```cs
105+
var properties = typeof(T).GetProperties();
106+
for (int col = 0; col < properties.Length; col++) {
107+
dataSheet.Cells[0, col].Value = properties[col].Name;
108+
}
109+
```
110+
111+
1. Iterate through dataset records and populate worksheet cells with associated values.
112+
113+
```cs
114+
var dataList = data.ToList();
115+
for (int row = 0; row < dataList.Count; row++) {
116+
for (int col = 0; col < properties.Length; col++) {
117+
var value = properties[col].GetValue(dataList[row]);
118+
var cell = dataSheet.Cells[row + 1, col];
119+
switch (value) {
120+
case int intVal:
121+
cell.Value = intVal;
122+
break;
123+
case DateTime dateVal:
124+
cell.Value = dateVal;
125+
cell.NumberFormat = "m/d/yyyy";
126+
break;
127+
case string strVal:
128+
cell.Value = strVal;
129+
break;
130+
}
131+
}
132+
}
133+
```
134+
135+
1. Add a new worksheet and create a [Spreadsheet Pivot Table](https://docs.devexpress.com/OfficeFileAPI/118492/spreadsheet-document-api/pivot-tables) based on data listed in the first worksheet.
136+
137+
```cs
138+
int lastRow = dataList.Count;
139+
int lastCol = properties.Length - 1;
140+
var sourceRange = dataSheet.Range.FromLTRB(0, 0, lastCol, lastRow);
141+
142+
var pivotSheet = workbook.Worksheets.Add("PivotTable");
143+
workbook.Worksheets.ActiveWorksheet = pivotSheet;
144+
var pivotTable = pivotSheet.PivotTables.Add(sourceRange, pivotSheet["A1"]);
145+
```
146+
147+
1. To recreate our Blazor Pivot Table's layout, iterate through [persistent layout fields](https://docs.devexpress.com/Blazor/DevExpress.Blazor.PivotTable.PivotTablePersistentLayout.Fields) and add them to corresponding Spreadsheet Pivot Table areas.
148+
149+
```cs
150+
var layoutFields = layout.Fields
151+
.Where(f => f.Area.HasValue && f.Visible != false)
152+
.OrderBy(f => f.AreaIndex)
153+
.ToList();
154+
var addedColumnFields = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
155+
156+
foreach (var layoutField in layoutFields) {
157+
var fieldName = layoutField.Field;
158+
var pivotField = FindPivotField(pivotTable, fieldName);
159+
160+
switch (layoutField.Area) {
161+
case PivotTableArea.Row:
162+
pivotTable.RowFields.Add(pivotField);
163+
break;
164+
case PivotTableArea.Column:
165+
pivotTable.ColumnFields.Add(pivotField);
166+
break;
167+
case PivotTableArea.Data:
168+
pivotTable.DataFields.Add(pivotField);
169+
break;
170+
case PivotTableArea.Filter:
171+
pivotTable.PageFields.Add(pivotField);
172+
break;
173+
}
174+
}
175+
```
176+
177+
1. _Optional._ Customize exported data fields based on configuration object settings.
178+
179+
```cs
180+
switch (layoutField.Area) {
181+
case PivotTableArea.Data:
182+
var dataField = pivotTable.DataFields.Add(pivotField);
183+
if (config.DataFieldConfigs.TryGetValue(fieldName, out var dfConfig)) {
184+
dataField.SummarizeValuesBy = dfConfig.SummaryFunction;
185+
if (!string.IsNullOrEmpty(dfConfig.Caption))
186+
dataField.Name = dfConfig.Caption;
187+
}
188+
break;
189+
//...
190+
}
191+
```
192+
193+
1. _Optional._ Call the [GroupItems](https://docs.devexpress.com/OfficeFileAPI/DevExpress.Spreadsheet.PivotField.GroupItems(DevExpress.Spreadsheet.PivotFieldGroupByType)) method to group exported date fields.
194+
195+
```cs
196+
foreach (var kvp in config.ColumnFieldGroupings) {
197+
var pivotField = FindPivotField(pivotTable, kvp.Key);
198+
if (pivotField != null)
199+
pivotField.GroupItems(kvp.Value.GroupBy);
200+
}
201+
```
202+
203+
1. Call the [SaveDocument{Async}](https://docs.devexpress.com/OfficeFileAPI/DevExpress.Spreadsheet.Workbook.SaveDocument.overloads?p=netframework) method to export the generated document.
204+
205+
```cs
206+
using var stream = new MemoryStream();
207+
workbook.SaveDocument(stream, DocumentFormat.Xlsx);
208+
return stream.ToArray();
209+
```
210+
211+
212+
## Files to Review
213+
214+
* [Index.razor](./Pages/Index.razor)
215+
* [PivotTableExportService.cs](./Services/PivotTableExportService.cs)
216+
217+
## Documentation
218+
219+
- [DevExpress Blazor Pivot Table](https://docs.devexpress.com/Blazor/405245/components/pivot-table)
220+
- [DevExpress Blazor Pivot Table - Save and Restore Layout](https://docs.devexpress.com/Blazor/405458/components/pivottable/save-and-restore-layout)
221+
- [DevExpress Office File API - Spreadsheet Pivot Tables](https://docs.devexpress.com/OfficeFileAPI/118492/spreadsheet-document-api/pivot-tables)
46.8 KB
Loading

0 commit comments

Comments
 (0)