Master-detail reports display hierarchical data where each master record (parent) has associated detail records (children). GroupDocs.Assembly for Java supports master-detail reports through nested foreach data bands, allowing you to display parent records with their related child records.
Here are the steps to generate master-detail reports:
Define data structures with parent-child relationships
Create a template with nested foreach data bands
Outer foreach iterates over master records
Inner foreach iterates over detail records for each master
Assemble the document with your hierarchical data
Note
Nested foreach data bands allow you to create complex hierarchical reports. The outer band processes master records, while inner bands process related detail records.
Define Master-Detail Data Structure
Start by defining classes with parent-child relationships:
Because of Java type erasure, the engine cannot determine the item type of a java.util.List passed directly as a data source. That is why the master records are passed as an array (Order[]) below. Detail collections returned by getters such as List<OrderItem> getItems() work fine, because the engine reads the item type from the getter’s declared return type.
Generate Master-Detail Report
Create a master-detail report from hierarchical data:
importcom.groupdocs.assembly.*;importjava.util.*;importjava.util.Date;publicstaticvoidgenerateMasterDetailReport()throwsException{// Create sample data with master-detail relationship
Order[]orders={newOrder(1001,newGregorianCalendar(2024,Calendar.JANUARY,15).getTime(),"John Doe",Arrays.asList(newOrderItem("Laptop",1,999.99),newOrderItem("Mouse",2,29.99))),newOrder(1002,newGregorianCalendar(2024,Calendar.JANUARY,16).getTime(),"Jane Smith",Arrays.asList(newOrderItem("Keyboard",1,79.99)))};// Assemble document
DocumentAssemblerassembler=newDocumentAssembler();assembler.assembleDocument("MasterDetailTemplate.docx","MasterDetailOutput.docx",newDataSourceInfo(orders,"orders"));System.out.println("Master-detail report generated successfully.");}
Template Structure for Master-Detail
In your template (MasterDetailTemplate.docx), use nested foreach data bands:
Members of Java objects are accessed through their getter methods. Date format strings follow the java.text.SimpleDateFormat pattern syntax, and number format strings follow the java.text.DecimalFormat pattern syntax (decimal and grouping separators depend on the current locale). After assembly, you’ll get:
Order #1001
Date: 2024-01-15
Customer: John Doe
Items:
- Laptop (Qty: 1, Price: $999.99)
- Mouse (Qty: 2, Price: $29.99)
Total: $1,059.97
Order #1002
Date: 2024-01-16
Customer: Jane Smith
Items:
- Keyboard (Qty: 1, Price: $79.99)
Total: $79.99
Master-Detail in Tables
You can also create master-detail reports in table format:
The outer table-row data band spans both rows: it starts at the beginning of the first cell of the master row and ends at the end of the last cell of the detail row. The inner data band covers the detail row only, so it is repeated for each order item.
Using Aggregates in Master-Detail
Calculate totals and aggregates for each master record:
importcom.groupdocs.assembly.*;importjava.util.*;publicstaticvoidgenerateMasterDetailWithAggregates()throwsException{Order[]orders={newOrder(1001,"John Doe",Arrays.asList(newOrderItem("Laptop",1,999.99),newOrderItem("Mouse",2,29.99)))};DocumentAssemblerassembler=newDocumentAssembler();assembler.assembleDocument("MasterDetailAggregatesTemplate.docx","MasterDetailAggregatesOutput.docx",newDataSourceInfo(orders,"orders"));System.out.println("Master-detail report with aggregates generated successfully.");}
Template with aggregates (MasterDetailAggregatesTemplate.docx):
When using nested foreach data bands, ensure proper closing tags. Each opening <<foreach>> tag must have a corresponding closing <</foreach>> tag.
Advanced Usage Topics
To learn more about complex hierarchical structures, multiple levels of nesting, and advanced master-detail patterns, please refer to the advanced usage section.
More resources
GitHub Examples
You may easily run the code above and see the feature in action in our GitHub examples: