Question about layout for a specific use case

1 Answer 32 Views
General Discussions
Francis
Top achievements
Rank 1
Francis asked on 28 Mar 2025, 09:24 AM

Hi all,

I'm developing a report and I don't know how to layout it.

The data source is a JSON DataSource and his structure is the following :



public class School
{
	public string Name { get; set; }
	public List<Class> Classes { get; set; }
}

public class Class
{
	public string Name { get; set; }
	public List<Student> Students { get; set; }
	public List<Teacher> Teachers { get; set; }
}

public class Student
{
	public string FirstName { get; set; }
	public string LastName { get; set; }
}

public class Teacher
{
	public string FirstName { get; set; }
	public string LastName { get; set; }
	public string Role { get; set; }
}

The desired layout is illustrated on the join file DesiredLayout.png and the report definition is joined too (containing datasource).

As you can see in the report definition, I don't use Header section. Because my list of teachers, on the top right, cannot be in a Header section.

And my problem is when the list of students for one class take more than one page, the school name, the class name and the list of teachers don't repeat.

My second problem is for the numbering on the footer. I don't know how to make it correctly.

Thank you for your help, regards
Krasimir
Top achievements
Rank 3
Iron
Iron
Iron
commented on 28 Mar 2025, 04:28 PM

Hello Francis,

You are using hierarchical JSON data. In this case you can use bindings to set the data within the reports. All data sources seem to have the same feed. If that is the case, I'd suggest that you use a single JSON data source. See the attached example. 

You can pay attention to the following:

1. You can bind the data sources for the nested elements like this

2. In order to have table headers printed on every page, you can set the "ColumnHeadersPrintOnEveryPage" property to True.

I didn't manage to resolve to topic with the paging numbers. Is that critical? I have a couple of ideas I can try but that could make the report a bit more complex.

Regards,
Krasimir Baylov

Krasimir
Top achievements
Rank 3
Iron
Iron
Iron
commented on 28 Mar 2025, 04:45 PM | edited

Ah, and now I understood your problem in a better way. I could try to provide some ideas in the next few days. Let's see if anyone else would manage to handle this, too.

By the way, what is the expectation for the page numbers? Should they be based on the total number of pages or should be reset when a new school, class starts?

--Krasimir Baylov

Francis
Top achievements
Rank 1
commented on 31 Mar 2025, 07:29 AM

Thank you Krasimir,

1) yes, it's much simpler with only one data source ! Thank you (and sorry, I'm new to Telerik Reporting ;) ).

2) Your proposal works for the header of the table of students. But It's not the problem. The problem is for School name, Class name, and list of teachers. They only appears on first page of each classes. And I need that they appears on each pages.

3) The page numbering must reset for every class (the school is the same for all the classes).

1 Answer, 1 is accepted

Sort by
0
Dimitar
Telerik team
answered on 01 Apr 2025, 02:05 PM

Hello Francis,

Thank you for the attached files and the additional information!

The approach that Krasimir has recommended with using one data source component and binding the nested fields to data items that display the nested data could indeed be used. You can take a look at the Using Nested Collection Properties for Building Hierarical Table - Telerik Reporting article for more such examples.

Regarding the last two requirements from the last reply, the first one - repeating the School name, Class name, and list of teachers on each page, can be achieved with what Krasimir previously recommended - using the ColumnHeadersPrintOnEveryPage property and a report group.

Create a report group based on the "Name" field of the top-level data - Adding a group to a Report using Report Designer, this is where the school name will be displayed. The report group automatically creates a group header and footer sections, and we can set the header to have PrintOnEveryPage=True so that the school name is displayed on every page.

Then for the class and teachers, instead of using a list for the "Classes" field's data, we can use a table since it comes with a predefined column header row, and we can put this information there and set ColumnHeadersPrintOnEveryPage=True, for example:

The last requirement is the hardest to implement as it requires 2 data sources. I am not sure if you wish to split the data like this so I will only suggest how it can be implemented while the above suggestions I already have prepared a demonstration for by editing Krasimir's sample report.

Essentially, the PageNumber and PageCount functions accept arguments. You may use the 'scope' to ensure they are evaluated for the corresponding group. Use the group name as a value for 'scope' and the grouping field for the 'aggregateFunction)', for example like below:

Page {PageNumber('group1', Fields.Name)} of {PageCount('group1', Fields.Name)}

The problem here is that the top-level data has the name of the school, it is not an array of objects with the classes information so we do not have access to the classes data at the top-level, thus cannot do the count for the classes.

If you are A workaround to achieve the desired functionality is to change the data or to use a data selector to get the "Classes" array directly - Using JSONPath to Filter JSON data - Telerik Reporting, so that the report group can be based on the name of the class rather than the school. This approach would require you to pass the school name via a report parameter, for example, since the report will have access to the data of the classes only.

I hope that the provided information is helpful. Please let us know if you have any additional questions.

Regards,
Dimitar
Progress Telerik

Enjoyed our products? Share your experience on G2 and receive a $25 Amazon gift card for a limited time!

Francis
Top achievements
Rank 1
commented on 07 Apr 2025, 03:08 PM

Thank you Dimitar,

now my layout is ok. The only thing I can't make working is the page numbering. I tried multiple scenarios with the PageNumer function, but nothing is printed on the preview. Is it a place where weh can see what happend when a text box is not rendered ?

I attach the last version of my report. If you do a print preview, you will see 4 pages for 3 classes. So the desired numbering is :

Page 1

Page 1

Page 2

Page 1

Can you help me ?

Dimitar
Telerik team
commented on 10 Apr 2025, 02:39 PM

Hello Francis,

Thank you for the attached report with the sample!

To be able to page the report per group, a report group must be used. In order to create such a group, that's corresponding to the table data, we need to return the field directly as the available data of the JsonDataSource component. We achieve this with a data selector:

You may have a look at the Using JSONPath to Filter JSON data - Telerik Reporting article for more information on the topic of data selectors.

After that, you may remove the first "list" wrapper from the report since we will now start at 1 level deeper in the data. Create a report group based on the "Code" filed:

AAfter that, since the highest-level data of the JSON will now not be available, you can pass those fields as parameters, for example:

Lastly, you can change the expression where the page number is displayed to now take into account the report group that we created:

Page {PageNumber('group', Fields.Code)} of {PageCount('group', Fields.Code)}

I have attached an edited copy of the report where those changes are implemented, let me know if you have any questions about it.

 

Francis
Top achievements
Rank 1
commented on 25 Apr 2025, 09:15 AM

Thank you Dimitar,

Unfortunately, I'm not happy with your proposal. I'm currently evaluating Telerik Reporting with a view to finding a successor to Oracle Reports. We have around 800 reports that need to be migrated. With Oracle Reports, we can build a tree of groups and manage page numbering according to these groups. If a requirement as simple as this requires such a solution, it shows a limitation that could pose a problem for us. And perhaps other problems to come (some of our 800 reports are very complex).

Given the large number of reports we have, we want to keep things as simple as possible. We've therefore opted for a data source based on a JSON file (the example I've given you is a development version with hard-coded data) and no parameters to pass to the report at runtime. Your proposal goes against this principle of simplicity.

Isn't there some other way of achieving this page numbering?

Dimitar
Telerik team
commented on 29 Apr 2025, 03:09 PM

Hello Francis,

I am afraid that the only way to achieve "per-group" paging is to use the scope of the group in the PageNumber() page function. For the group to be available, it should be a report group which requires the data that the group will be based on to be at the top-level of the data source component.

With that being said, there is another approach besides using report parameters but I would say that it may be harder to implement. The other option is to edit the report programmatically and assign the data, not related to the groups, to the corresponding report items via code.

If you are interested in such an approach, you can take a look at the Managing Reports with code - Telerik Reporting article. Note that you would need to have custom code that reads the JSON data, extracts the JSON values, finds the report items in the report that it should edit, and then repackages the updated report - Packaging Report Definitions Explained - Telerik Reporting, or directly renders it for that data set with the InstanceReportSource object .

If you choose to give this approach a try, and you have additional questions, please let me know whether you intend to display the reports in a viewer or render them to dcuments directly so that i can have a better idea of your scenario. 

Tags
General Discussions
Asked by
Francis
Top achievements
Rank 1
Answers by
Dimitar
Telerik team
Share this question
or