Split data source records into subsets and display them on separate pages?

Hello Docentric, I have several data records (invoice lines) in my data source. I would like to divide the total number of these lines into subsets of 5 lines. These subsets of lines should then always be printed on a new page – with the table header being repeated for each new instance of the table. Is it possible to achieve something like this with Docentric? Let me know if you need additional explanation.

Hello, @JohnR, and thank you for your challenge :+1:

What you want to achieve is possible, and I have prepared a test template showing a possible approach based on the grouping of records.

On the first page of the test template there is a table displaying 12 invoice lines:

However, we want to display the same content in multiple tables (possibly on multiple pages), and each instance of the table should also show the table header - see below.

All instances of the above tables should display no more than 5 lines, while in the last table, the number of lines can be lower, depending on the total number of invoice lines.

Identifying the Group Key

The initial challenge is to find a common identifier (group key) that allows us to group the records into subsets. The approach we have chosen requires a brief explanation.

The invoice lines are first indexed using the index-of function. The Xpath expression (below, Exp1) is as follows:

index-of(data-source('MainData')/SalesInvoiceLines, .)

The index-of function accepts two parameters: the source node and the reference node. The above expression refers to the entire collection of SalesInvoiceLines records – source node – in the MainData section and returns the index of the current node (data record) within this collection. This reference node is specified by the second parameter (.) in the XPath expression below.

Since the returned index is one-based, we need to subtract 1 from the values. The XPath (Exp2) is now:

index-of(data-source('MainData')/SalesInvoiceLines, .) – 1

And since we want to divide the entire collection of data records into subsets of 5 data records each, we have to divide the expression by 5 (Exp3):

(index-of(data-source('MainData')/SalesInvoiceLines, .) - 1) div 5

Finally, we use the floor function to floor the values returned from the expression above (Exp4)

floor((index-of(data-source('MainData')/SalesInvoiceLines, .) - 1) div 5)

As you can see, the floored values we get from the last expression (Exp4) are the same for the first five records (the value is zero) and then increase by one for each additional set of 5 records.

Replicating Tables with Group Tagging Element

Next, on the second page, we have implemented a Group tagging element (below, 1) on top of the original table to replicate this table multiple times. As you can see below, we use the latest version of the XPath expression as the group key (2), resulting in three instances of the table (3), with each table containing a maximum of 5 records.

We can split the repeating data records into subsets using the above approach.

Adapting XPath for Different Subset Sizes

We can also change the XPath expression we use as the group key if needed. For example, if each table is to contain more records, e.g. 6, the following expression can be used:

floor((index-of(data-source('MainData')/SalesInvoiceLines, .) - 1) div 6)

The only change in XPath is the division by 6 instead of the division by 5, which results in two tables, each containing 6 data records (lines):

Here are the test templates:
Fixed number of records per page - initial.docx (147.4 KB)
Fixed number of records per page - final with group.docx (150.4 KB)

Let me know if the above example makes sense in your case or if you need additional help.

Hello @JernejV that was exactly what I wanted, and I succesfully implemented this in my custom template.

There was just one missing piece, but I have solved the puzzle by simply adding the page breaks inside the groups so that tables now always print on a new page. Thank you for providing the explanation and approach!