Bank statement
Generate a simple bank statement with Carbone
- Template type document docx expert
- Carbone min. v5.0.0+
- Features loop set count aggregator subtotal
- Target bank insurance quote custom
Objectives
Generate a bank statement with the following features:
- Limit the number of entries per page to a fixed amount.
- Display an intermediate balance on each page.
Solution
Since all entries are stored at the same level in the JSON array, and the goal is to display a fixed number per page, the solution is to restructure the JSON in the template with appropriate Carbone tags and then display it correctly.
Here’s how to create this type of template using Carbone:
Structuring data by page
Based on your layout, determine the number of block-lines that can fit on a single page (e.g.,
15
)Compute the objects to be displayed on the same page by:
Example :
{d.operations[]:cumCount():div(15):ceil:set(.numPage)}
At this stage, each object will have a new property named numPage
, indicating the page number where it will be displayed.
- Group objects that share the same
numPage
into a new array calledd.group
, using the :set formatter
Example:
{d.operations[]:set(d.group[id=.numPage].data[])}
- Leverage the newly grouped structure
d.group
in the template to display the data
Example : {d.group[i].data[i].transaction}
.
JSON Before
{
"operations": [
{ "transaction": "School fees payment",
"amount": -300 },
{...},
{ "transaction": "Supermarket shopping",
"amount": -130.2 },
{...}
]
}
JSON After
{
"operations": [...],
"group":[
{ "data": [
{ "transaction": "School fees payment",
"amount": -300,
"numPage": 1 },
{...}
]
},
{ "data": [
{ "transaction": "Supermarket shopping",
"amount": -130.2,
"numPage": 2 },
{...}
]
}
]
}
Subtotal computation
To print the subtotal per page, use the aggSum formatter.
Since there is a column for debits and a column for credits, the subtotals are computed as follows:
For debits (negative amounts), set positive amounts to
0
using:ifGTE(0):show(0)
beforeaggSum
:{d.group[i].data[].amount:ifGTE(0):show(0):aggSum:formatC}
For credits (positive amounts), set negative amounts to
0
using:ifLT(0):show(0)
beforeaggSum
:{d.group[i].data[].amount:ifLT(0):show(0):aggSum:formatC}
Intermediate balance computation
To print the intermediate balance, combine the aggSum formatter with the cumSum formatter, and add it to the open_bal stored in the JSON:
{d.group[i].data[].amount:aggSum:cumSum:add(...open_bal):formatC}`
Extra tip / Pagination
To ensure consistent rendering, insert a Page break between each page. Define it after the different elements to be displayed on the same page and before the iteration [i+1]
.
As a result, the report ends with a final blank page. To avoid this, delete the page break conditionally if the last element of the list is printed. Use the following formula on the paragraph of the page break: {d.group[i]..group:len():sub(1):ifEQ(.i):drop(p)}
, where
{d.list[i]
: Access the list element using the iterator[i]
, the indexi
will be used for the condition...group:len()
: Retrieve the length of the list by backtracking to the parent object.:sub(1)
: Subtract one from the list length, accounting for zero-based indexing. (The list length is counted from one, however the index from [i] is starting from zero.):ifEQ(.i):drop(p)}
: Delete the paragraph, including the page break, if the current index .i is equal to the list size, indicating the last element.
And there you go!
Alternatives
Trusted by 600+ paid customers in 40+ countries














