An oft-requested feature of the PDF filling API is to repeat pages within a PDF. You may have a PDF that has a page with a fixed list of empty fields, but more data than fits into the list of fields. We often see this with invoices, insurance documents, financial paperwork requiring beneficiaries, etc.
For example, here's the main block of an invoice template:
It only has room for 6 items. But what if you need to generate this invoice with 10 line items? The PDF is static! The table will not grow to accept the necessary 10 items. What do you do?
Repeat the page with the remaining items!
Anvil's PDF filling API endpoint now supports PDF page repeating. You can repeat any page in any PDF, even pages in the middle of a multi-page PDF. Let's see it in action.
Set up your template for repeats
We'll use the invoice mentioned above as an example. First sign up for Anvil, then get your API keys.
You can use the same invoice template PDF I am using to follow along. Upload the PDF to your PDF template library in the Anvil dashboard. After upload, you'll see something like:
To enable the page repeating in this invoice scenario, a new feature allows you to create an Array with any number of children fields. We will be creating an array for each column in the invoice table: Description
, Quantity
, Unit Price
, Amount
, then we'll send each column's array an Array
of data to fill the PDF.
To create an array, make sure you have your template in edit mode, click on the first item in your array, then move to the field editor's advanced tab:
Click Create an array
, for each item in the array, click add another item
, then click the item you want to add. When you're done, it will look like this:
Back on the options tab, you can set the id
of the array field for easy filling. For example, I set it to amounts
for this column:
Now you can send this column an array of data to fill some or all of the fields. Click over to the template page's API info tab to see the payload to fill this array:
{
"title": "Invoice 1234",
"textColor": "#CC0000",
"data": {
"invoiceId": "#1234",
"amounts": [
1.11,
2.22,
3.33,
4.44,
5.55,
6.66,
]
}
}
POSTing to the PDF template with the data above yields all amounts filled. Item [0]
will go in the first box, item [1]
in the second, etc.
Now set up the other columns—Description
, Quantity
, Unit Price
— the same way you did with the Amounts
and you'll be off to the races.
{
"title": "Invoice 1234",
"textColor": "#CC0000",
"data": {
"invoiceId": "#1234",
"descriptions": [
'Widget #1',
'Widget #2',
'Widget #3',
'Widget #4',
'Widget #5',
'Widget #6'
],
"quantities": [1, 2, 3, 4, 5, 6],
"unitPrices": [1.11, 2.22, 3.33, 4.44, 5.55, 6.66],
"amounts": [1.11, 4.44, 9.99, 17.76, 27.75, 39.96]
}
}
Repeating the page
Once your template is set up, repeating a page is super simple:
Send an array of data with more items than spaces available in the PDF’s Array field.
The previous examples had only 6 items in each array. Sending any additional items will tell Anvil to repeat the page. It will repeat the page until all items in your array are rendered on a page.
{
"title": "Invoice 1234",
"textColor": "#CC0000",
"data": {
"invoiceId": "#1234",
"descriptions": [
'Widget #1',
'Widget #2',
'Widget #3',
'Widget #4',
'Widget #5',
'Widget #6',
'Widget #7' // Extra item!
],
"quantities": [1, 2, 3, 4, 5, 6, 7],
"unitPrices": [1.11, 2.22, 3.33, 4.44, 5.55, 6.66, 7.77],
"amounts": [1.11, 4.44, 9.99, 17.76, 27.75, 39.96, 54.39]
}
}
Note that non-array data like Invoice ID
above is repeated across all pages. There are ways to control this, but we'll cover them in subsequent blog posts.
Filling page numbers
You may have noticed the page numbers in the screenshot above. Page numbers can be injected into the PDF as well.
First make sure your template is in order. All you need is a field or fields for the page number, total, etc. These are just Short Text fields—no special setup necessary. I've given mine id
s of pageNumber
and totalPages
:
Now send those fields a template string with a page number variable e.g. '{{pageNumber}}'
{
"title": "Invoice 1234",
"textColor": "#CC0000",
"data": {
"invoiceId": "#1234",
"amounts": [1.11, 4.44, 9.99, 17.76, 27.75, 39.96, 54.39]
...
"pageNumber": '{{pageNumber}}',
"totalPages": '{{totalPages}}'
}
}
Anvil will replace these variables with the correct data for each rendered page.
Template strings can be used to fill any Short Text or Long Text field. Several page-related variables are supported in template strings
pageNumber
- Page number within the PDFpageIndex
- 0-basedpageNumber
, i.e.pageNumber - 1
totalPages
- Total number of pages in the PDFpageRepeatNumber
- Page number within this repeat loop. It will be1
if there is no repeatingpageRepeatIndex
- 0-basedpageRepeatNumber
pageRepeatTotal
- Total number of pages within this repeat loop
Any number of these variables can be combined to output onto a single field. Just put them in the same string! For example, here is a Short Text field I've created called pageNumberAll
.
Simply send up a string using multiple variables:
{
"title": "Invoice 1234",
"textColor": "#CC0000",
"data": {
"invoiceId": "#1234",
...
"pageNumberAll": 'Page {{pageNumber}} of {{totalPages}}',
}
}
And it outputs in one field:
Conclusion
Filling a PDF with arbitrary-length data is an example of a situation where a physical process (with paper) is challenging to replicate in a software environment. Now you can repeat those PDF pages and fill all your fixed documents without worry.
Having covered some of the fundamental ways to manage page repeats within a PDF, we’ll be diving deeper into the more complex ways in subsequent blog posts. For now, check out the PDF filling API guide if you haven't already.
If you’re developing something cool with PDFs and/or paperwork automation, we’d love to hear more from you! Let us know at developers@useanvil.com.