Skip to content

Commit 957db76

Browse files
Merge pull request #590 from telerik/new-kb-grouping-data-using-radspreadprocessing-08eafa73d02a47098ab6e869fbc66668
Added new kb article grouping-data-using-radspreadprocessing
2 parents 6e7019a + be13a53 commit 957db76

File tree

3 files changed

+181
-0
lines changed

3 files changed

+181
-0
lines changed
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
---
2+
title: Grouping Data Example Using RadSpreadProcessing
3+
description: Learn how to group data in a worksheet using RadSpreadProcessing for Document Processing.
4+
type: how-to
5+
page_title: How to Group Data in RadSpreadProcessing
6+
meta_title: How to Group Data in RadSpreadProcessing
7+
slug: grouping-data-using-radspreadprocessing
8+
tags: document, processing, group, column, excel, spread
9+
res_type: kb
10+
ticketid: 1692310
11+
---
12+
13+
<style>
14+
img[alt$="><"] {
15+
border: 1px solid lightgrey;
16+
}
17+
</style>
18+
19+
## Environment
20+
21+
| Version | Product | Author |
22+
| ---- | ---- | ---- |
23+
| 2025.2.520| RadSpreadProcessing |[Desislava Yordanova](https://www.telerik.com/blogs/author/desislava-yordanova)|
24+
25+
## Description
26+
27+
This article shows how to generate a worksheet with **grouped** data from a **flat** collection of records as an input.
28+
29+
>caption Flat vs. Grouped Data
30+
31+
![Flat vs Grouped Data in Excel ><](images/build-grouped-data-in-spreadprocessing.png)
32+
33+
## Solution
34+
35+
Note that the grouping should be performed separately beforehand, and only then can the Worksheet be populated with the grouped data.
36+
37+
Once you have the grouped data, the SpreadProcessing functionality (in a similar way to MS Excel) allows you to assign the outline level to all rows that belong to the same group.
38+
To make it clear and simple, let's take the following example - a flat list of products stored in CSV data:
39+
40+
### Preparing Grouped Data
41+
42+
1. Group your flat data (e.g. Northwind.Products) before populating the worksheet.
43+
2. Use LINQ or other methods to group rows based on a specific column (e.g. CategoryID).
44+
45+
Use the following code snippet to group rows in a worksheet:
46+
47+
```csharp
48+
internal class Program
49+
{
50+
static void Main(string[] args)
51+
{
52+
string fileName = "sample.csv";
53+
Workbook workbook;
54+
55+
CsvFormatProvider csv_formatProvider = new CsvFormatProvider();
56+
57+
using (Stream input = new FileStream(fileName, FileMode.Open))
58+
{
59+
workbook = csv_formatProvider.Import(input, TimeSpan.FromSeconds(10));
60+
61+
}
62+
Worksheet worksheet = workbook.ActiveWorksheet;
63+
64+
// Convert worksheet data to DataTable
65+
DataTable dataTable = WorksheetToDataTable(worksheet);
66+
67+
// Apply grouping and outlining
68+
Workbook groupedWorkbook= ApplyGroupingToWorksheet(dataTable, new Workbook());
69+
70+
Telerik.Windows.Documents.Spreadsheet.FormatProviders.IWorkbookFormatProvider xlsx_formatProvider =
71+
new Telerik.Windows.Documents.Spreadsheet.FormatProviders.OpenXml.Xlsx.XlsxFormatProvider();
72+
73+
string outputFilePath = "output.xlsx";
74+
File.Delete(outputFilePath);
75+
using (Stream output = new FileStream(outputFilePath, FileMode.Create))
76+
{
77+
xlsx_formatProvider.Export(workbook, output, TimeSpan.FromSeconds(10));
78+
}
79+
80+
Process.Start(new ProcessStartInfo() { FileName = outputFilePath, UseShellExecute = true });
81+
82+
outputFilePath = "groupedOutput.xlsx";
83+
File.Delete(outputFilePath);
84+
using (Stream output = new FileStream(outputFilePath, FileMode.Create))
85+
{
86+
xlsx_formatProvider.Export(groupedWorkbook, output, TimeSpan.FromSeconds(10));
87+
}
88+
89+
Process.Start(new ProcessStartInfo() { FileName = outputFilePath, UseShellExecute = true });
90+
}
91+
static DataTable WorksheetToDataTable(Worksheet worksheet)
92+
{
93+
DataTable dataTable = new DataTable();
94+
95+
// Get used range
96+
CellRange usedRange = worksheet.UsedCellRange;
97+
98+
// Add columns to DataTable (assuming first row contains headers)
99+
for (int col = 0; col < usedRange.ColumnCount; col++)
100+
{
101+
string columnName = worksheet.Cells[0, col].GetValue().Value.RawValue.ToString();
102+
dataTable.Columns.Add(columnName ?? $"Column{col}");
103+
}
104+
105+
// Add data rows
106+
for (int row = 1; row < usedRange.RowCount; row++)
107+
{
108+
DataRow dataRow = dataTable.NewRow();
109+
for (int col = 0; col < usedRange.ColumnCount; col++)
110+
{
111+
dataRow[col] = worksheet.Cells[row, col].GetValue().Value.RawValue ?? string.Empty;
112+
}
113+
dataTable.Rows.Add(dataRow);
114+
}
115+
116+
return dataTable;
117+
}
118+
119+
static Workbook ApplyGroupingToWorksheet(DataTable dataTable, Workbook workbook)
120+
{
121+
// Group the data by the sixth column (index 5)
122+
var groupedResults = from p in dataTable.AsEnumerable()
123+
group p by p.Field<string>("categoryID") into g
124+
select new
125+
{
126+
categoryID = g.Key,
127+
productID = string.Join(";", from i in g select i.Field<string>("productID")),
128+
productName = string.Join(";", from i in g select i.Field<string>("productName")),
129+
quantityPerUnit = string.Join(";", from i in g select i.Field<string>("quantityPerUnit")),
130+
CustomunitPriceerLastname = string.Join(";", from i in g select i.Field<string>("unitPrice")),
131+
unitsInStock = string.Join(";", from i in g select i.Field<string>("unitsInStock")),
132+
unitsOnOrder = string.Join(";", from i in g select i.Field<string>("unitsOnOrder"))
133+
};
134+
135+
136+
workbook.Worksheets.Add();
137+
Worksheet worksheet = workbook.ActiveWorksheet;
138+
worksheet.Cells[0, 1].SetValue("productID");
139+
worksheet.Cells[0, 2].SetValue("productName");
140+
worksheet.Cells[0, 3].SetValue("quantityPerUnit");
141+
worksheet.Cells[0, 4].SetValue("unitPrice");
142+
// Header is row 0, data starts at row 1
143+
int currentRow = 1;
144+
145+
// Process each group
146+
foreach (var group in groupedResults)
147+
{
148+
worksheet.Cells[currentRow, 1].SetValue("CategoryID "+group.categoryID);
149+
currentRow++;
150+
151+
string[] productsIDs= group.productID.Split(';');
152+
string[] productNames = group.productName.Split(';');
153+
string[] quantityPerUnits = group.quantityPerUnit.Split(';');
154+
string[] unitPrices = group.CustomunitPriceerLastname.Split(';');
155+
string[] unitsInStocks = group.unitsInStock.Split(';');
156+
string[] unitsOnOrders = group.unitsOnOrder.Split(';');
157+
158+
int start = currentRow;
159+
int end= currentRow+ productsIDs.Length - 1;
160+
for (int i = 0; i < productsIDs.Length; i++)
161+
{
162+
worksheet.Cells[currentRow, 1].SetValue(productsIDs[i]);
163+
worksheet.Cells[currentRow, 2].SetValue(productNames[i]);
164+
worksheet.Cells[currentRow, 3].SetValue(quantityPerUnits[i]);
165+
worksheet.Cells[currentRow, 4].SetValue(unitPrices[i]);
166+
worksheet.Cells[currentRow, 5].SetValue(unitsInStocks[i]);
167+
worksheet.Cells[currentRow, 6].SetValue(unitsOnOrders[i]);
168+
currentRow++;
169+
}
170+
worksheet.Rows[start, end].Group();
171+
}
172+
return workbook;
173+
}
174+
}
175+
```
176+
Modify the example to suit your specific data structure and requirements.
177+
178+
## See Also
179+
180+
- [Grouping in SpreadProcessing]({%slug radspreadprocessing-features-grouping%})
408 KB
Loading

libraries/radspreadprocessing/features/grouping.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,4 +189,5 @@ Both properties have a default value of true. The following snippet shows how to
189189

190190
* [Filtering]({%slug radspreadprocessing-features-filtering%})
191191
* [Sorting]({%slug radspreadprocessing-features-sorting%})
192+
* [Grouping Data Example Using RadSpreadProcessing]({%slug grouping-data-using-radspreadprocessing%})
192193

0 commit comments

Comments
 (0)