Advanced Invoice With Multiple Pages - TEMPLATES-SAMPLES
PDF from HTML Template sample in TEMPLATES-SAMPLES demonstrating ‘Advanced Invoice With Multiple Pages’
data.json
{
"paid": true,
"company_name": "Lovely Company Inc.",
"company_address": "1234 Market St\nSan Francisco, California 94102\nUSA",
"company_logo": "https://bytescout-com.s3.amazonaws.com/files/demo-files/cloud-api/pdf-edit/logo.png",
"barcode_value": "sample encoded barcode value for page 1\nwuth line breaks if needed\n\nOrder id:",
"ocr_scanline": "OCR-A 123567890",
"order_id": "1122455",
"order_date": "15 Jan 2022",
"customer_id": "T8001",
"shipped_date": "20 Jan 2022",
"shipped_via": "UPS",
"bill_to_name": "T-800 Research Lab",
"bill_to_address": "435 South La Fayette Park Place, \nLos Angeles, CA 90057\nUSA",
"ship_to_name": "Cyberdyne Systems",
"ship_to_address": "18144 El Camino Real\nSunnyvale, California\nUSA",
"freight": 19.95,
"notes": "Thank you for your purchase.\nThanks for your support of advanced robotics.",
"items": [
{
"name": "T-800 Prototype Research",
"price": 50.0,
"quantity": 2
},
{
"name": "T-800 Cloud Sync Setup",
"price": 150.0,
"quantity": 3
},
{
"name": "T-800 Prototype Research 2",
"price": 20.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 24.99,
"quantity": 5
},
{
"name": "T-800 Prototype Research 2",
"price": 199.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 19.0,
"quantity": 5
},
{
"name": "T-800 Prototype Research 2",
"price": 20.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 49.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 1000.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 10.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 12.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 25.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 24.99,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 14.95,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 149.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 99.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 10.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 100.0,
"quantity": 4
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 10.0,
"quantity": 9
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 5
},
{
"name": "T-800 Prototype Research 2",
"price": 10.0,
"quantity": 3
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 2
}, {
"name": "T-800 Prototype Research 2",
"price": 10.0,
"quantity": 3
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 3
}, {
"name": "T-800 Prototype Research 2",
"price": 3.49,
"quantity": 3
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 10.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 10.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 10.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 15.0,
"quantity": 5
},
{
"name": "T-800 Prototype Research",
"price": 50.0,
"quantity": 2
},
{
"name": "T-800 Cloud Sync Setup",
"price": 150.0,
"quantity": 3
},
{
"name": "T-800 Prototype Research 2",
"price": 20.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 24.99,
"quantity": 5
},
{
"name": "T-800 Prototype Research 2",
"price": 199.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 19.0,
"quantity": 5
},
{
"name": "T-800 Prototype Research 2",
"price": 20.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 49.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 1000.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 10.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 12.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 25.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 24.99,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 14.95,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 149.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 99.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 10.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 100.0,
"quantity": 4
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 10.0,
"quantity": 9
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 5
},
{
"name": "T-800 Prototype Research 2",
"price": 10.0,
"quantity": 3
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 2
}, {
"name": "T-800 Prototype Research 2",
"price": 10.0,
"quantity": 3
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 3
}, {
"name": "T-800 Prototype Research 2",
"price": 3.49,
"quantity": 3
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 10.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 10.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 10.0,
"quantity": 1
},
{
"name": "T-800 Prototype Research",
"price": 50.0,
"quantity": 2
},
{
"name": "T-800 Cloud Sync Setup",
"price": 150.0,
"quantity": 3
},
{
"name": "T-800 Prototype Research 2",
"price": 20.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 24.99,
"quantity": 5
},
{
"name": "T-800 Prototype Research 2",
"price": 199.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 19.0,
"quantity": 5
},
{
"name": "T-800 Prototype Research 2",
"price": 20.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 49.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 1000.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 10.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 12.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 25.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 24.99,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 14.95,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 149.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 99.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 10.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 100.0,
"quantity": 4
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 10.0,
"quantity": 9
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 5
},
{
"name": "T-800 Prototype Research 2",
"price": 10.0,
"quantity": 3
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 2
}, {
"name": "T-800 Prototype Research 2",
"price": 10.0,
"quantity": 3
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 3
}, {
"name": "T-800 Prototype Research 2",
"price": 3.49,
"quantity": 3
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 10.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 10.0,
"quantity": 1
},
{
"name": "T-800 Cloud Sync Setup 3",
"price": 30.0,
"quantity": 5
}, {
"name": "T-800 Prototype Research 2",
"price": 10.0,
"quantity": 1
}
]
}
template.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Invoice {{order_id}}</title>
<!-- PDF.co templates use Handlebars (advanced version of {{Moustache}} templates -->
<!-- We can define our own HandleBarsJS helpers to calculate discounts, total amounts, formatting strings etc. See https://handlebarsjs.com/api-reference/runtime.html#handlebars-registerhelper-name-helper -->
<script type="text/javascript">
// helper functions to calculate total, breaklines for text etc
Handlebars.registerHelper('breaklines', function (text) {
text = Handlebars.Utils.escapeExpression(text);
text = text.replace(/(\n|\r)/gm, '<br />');
return new Handlebars.SafeString(text);
});
Handlebars.registerHelper('getTotal', function (quantity, price) {
var total = quantity * price;
return total;
});
Handlebars.registerHelper('getTotalLines', function (items) {
var total = 0;
items.forEach(function (line) {
total += line.quantity * line.price;
});
return total;
});
// format number to add comma separators for thousands
Handlebars.registerHelper('numberFormat', numberFormat);
function numberFormat(value) {
// Helper parameters
var dl = 2;
var ts = ',';
var ds = '.';
// Parse to float
var value = parseFloat(value);
// The regex
var re = '\\d(?=(\\d{3})+' + (dl > 0 ? '\\D' : '$') + ')';
// Formats the number with the decimals
var num = value.toFixed(Math.max(0, ~~dl));
// Returns the formatted number
return (ds ? num.replace('.', ds) : num).replace(new RegExp(re, 'g'), '$&' + ts);
}
Handlebars.registerHelper('getFinalAmount', function (items, freight) {
var total = 0;
items.forEach(function (line) {
total += line.quantity * line.price;
});
return total + freight;
});
</script>
<!-- formatting and page size is based on PagedJS open-source framework from https://www.pagedjs.org/ -->
<!-- <script src="https://unpkg.com/pagedjs@0.2.0/dist/paged.polyfill.js"></script> -->
<!-- using version 0.20 PagedJS from bytescout hosting -->
<script src="https://bytescout-com.s3.us-west-2.amazonaws.com/files/cloudapi-templates/paged.polyfill-020.js"></script>
<!-- should be the last script in the header. Handlebars utilities should come first -->
<script defer type="text/javascript">
class InvoicePageHandler extends Paged.Handler {
constructor(chunker, polisher, caller) {
super(chunker, polisher, caller);
}
afterRendered(pages) {
// logic to show/hide elements on ecah page
for (let i = 0; i < pages.length; i++) {
const curPage = pages[i];
let curPageElements = curPage.element;
// page number in the items header
curPage.element.getElementsByClassName("spnPageNumberInTitle")[0].innerHTML = `Page ${i + 1} of ${pages.length}`;
// first page
// enabling/disabling elements
if (i === 0) {
// hide scanline
curPage.element.getElementsByClassName("clsScanLineOCR")[0].remove();
// page number footer
//curPage.element.getElementsByClassName("pageNumber")[0].remove();
}
else {
// or remove the default one
curPage.element.getElementsByClassName("clsScanLineDefault")[0].remove();
}
// if not very last page
if (i != pages.length - 1) {
// the footer with total etc
curPage.element.getElementsByClassName("spnTotal")[0].remove();
curPage.element.getElementsByClassName("spnSubTotal")[0].remove();
curPage.element.getElementsByClassName("spnFreight")[0].remove();
// paid watermark
if (curPage.element.getElementsByClassName("clsImgPaid").length > 0) {
curPage.element.getElementsByClassName("clsImgPaid")[0].remove();
}
}
else {
// the very last page
// hide "Continue..." block
curPage.element.getElementsByClassName("spnContinued")[0].remove();
}
}
}
}
Paged.registerHandlers(InvoicePageHandler);
</script>
<style>
/* font with OCR A Extended face */
@font-face {
font-family: 'OCR A Extended';
font-style: normal;
font-weight: 400;
src: url('https://fonts.cdnfonts.com/s/14159/OCRAEXT_2.woff') format('woff');
}
/* Print related stylesheet */
@media print {
/* Styling Page */
@page {
/* Setting Page Size to Letter. Find different page sizes at https://pagedjs.org/documentation/5-web-design-for-print/#page-size-property */
size: letter;
/* Setting Page Margin of 10 mm */
margin: 10mm;
/* Leaving padding of 107mm from top. This is to adjust for header. */
padding-top: 107.0mm;
/* Leaving padding of 15mm from top. This is to adjust for footer. */
padding-bottom: 14.85mm;
/* Setting repeating header. For more details visit https://pagedjs.org/documentation/7-generated-content-in-margin-boxes/#styling-running-elements */
@top-center {
content: element(titleRunning);
height: 160.3mm;
padding-top: 10mm;
padding-bottom: 50mm;
}
/* Setting repeating footer. For more details visit https://pagedjs.org/documentation/7-generated-content-in-margin-boxes/#styling-running-elements */
@bottom-center {
content: element(footerRunning);
}
}
/* Class for repeatable header. Used inside @top-center */
.title {
position: running(titleRunning);
}
/* Class for repeatable footer. Used inside @bottom-denter */
.bottom_running {
position: running(footerRunning);
margin-bottom: 15mm;
}
/* Setting Page Number */
.pageNumber::after {
content: 'Page 'counter(page) ' of 'counter(pages);
}
/* Table and Other MISC CSS Styles */
td,
th {
padding: 3px;
}
table.tableStripe tr:nth-child(even) td {
background: #F1F1F1;
}
table.tableStripe tr:nth-child(odd) td {
background: #FEFEFE;
}
tr[data-last-split-element] {
display: none;
}
table#tblMain tr td:nth-child(1) {
border-right: solid 1px black;
width: 20mm;
}
table#tblMain tr td:nth-child(2) {
border-right: solid 1px black;
width: 116.35mm;
}
table#tblMain tr td:nth-child(3) {
border-right: solid 1px black;
width: 29.2mm;
}
table#tblMain tr td {
border-bottom: solid 1px black;
}
.spnPageNumberInTitle {
border-bottom: none !important;
}
.clsImgPaid {
position: absolute;
width: 100px;
right: 30%;
}
}
</style>
</head>
<body>
<!-- header begin -->
<section class="title">
<table style="width: 100%;">
<tr>
<td>
<table>
<tr>
<td>
<img src="{{ company_logo }}" />
</td>
</tr>
<tr>
<td style="text-align: left;">
{{ breaklines company_address }}
</td>
<td>
<div>
<img src="[[barcode: QRCode {{barcode_value}} {{order_id}} ]]" />
</div>
<br /><br />
<div style="font-family: 'OCR A Extended';">
<!-- this will appear on the 2nd page only -->
<div class="clsScanLineOCR">{{ ocr_scanline }}</div>
<div class="clsScanLineDefault">__________________</div>
</div>
</td>
</tr>
</table>
</td>
<td style="text-align: right;">
<h1 style="margin: 0;">Invoice</h1>
<table style=" float: right; border:solid 1px black; background-color: lightgreen;">
<tr>
<th>Order ID:</th>
<td>{{ order_id }}</td>
</tr>
<tr>
<th>Order Date:</th>
<td>{{ order_date }}</td>
</tr>
<tr>
<th>Customer ID:</th>
<td>{{ customer_id }}</td>
</tr>
<tr>
<th>Shipped Date:</th>
<td>{{ shipped_date }}</td>
</tr>
<tr>
<th>Shipped Via:</th>
<td>{{ shipped_via }}</td>
</tr>
</table>
</td>
</tr>
<tr>
<td colspan="2"></td>
</tr>
<tr>
<td>
<table style="border: solid 1px black;" cellpadding="0" cellspacing="0">
<tr>
<th style="text-align: left;">
Bill To:
</th>
</tr>
<tr>
<td style="text-align: left; border-top: solid 1px black;">
{{ bill_to_name }}<br />
{{ breaklines bill_to_address }}
</td>
</tr>
</table>
</td>
<td>
<table style="border: solid 1px black;" cellspacing="0">
<tr>
<th style="text-align: left;">
Ship To:
</th>
</tr>
<tr>
<td style="text-align: left; border-top: solid 1px black;">
{{ ship_to_name }}<br />
{{ breaklines ship_to_address }}
</td>
</tr>
</table>
</td>
</tr>
</table>
<table cellpadding="0" cellspacing="0" style="width:195mm;">
<tr>
<td colspan="3" style="border-right: solid 1px black;">
</td>
<td class="spnPageNumberInTitle" style="border-top:solid 1px black; border-right:solid 1px black;">
<span class="pageNumber"></span>
</td>
</tr>
<tr>
<th style="width: 20mm; border:solid 1px black;border-right: none;">Quantity</th>
<th style="width:116.5mm;border:solid 1px black; ">Description</th>
<th style="width:29.2mm; border:solid 1px black; border-left: none !important">Unit Price</th>
<th style="border:solid 1px black; border-left: none !important">Price</th>
</tr>
</table>
</section>
<!-- header end -->
<!-- footer begin -->
<section class="bottom_running">
{{#if paid}}
<div class="clsImgPaid"
style="border-width: 3px; color: green; opacity: 0.4; position: absolute; z-index: 1; left:10%; top:90%; font-size: 60pt;transform: rotate(-15deg)">
PAID
</div>
{{/if}}
<div style="border: solid 1px black; width: 195mm;">
<table class="tableStripe" style="width: 100%;" cellpadding="0" cellspacing="0">
<tr>
<th style="width: 136mm; border-right: solid 1px black;">
<span style="font-size: 18px;">
{{breaklines notes}}
</span>
</th>
<td>
<table cellpadding="0" cellspacing="0" style="width: 100%;">
<tr>
<th style="text-align: right; width: 28mm;">Sub-Total</th>
<td style="text-align: left;"> <span class="spnSubTotal">${{numberFormat (getTotalLines
items) }}</span></td>
</tr>
<tr>
<th style="text-align: right;">Freight</th>
<td style="text-align: left;"><span class="spnFreight">${{numberFormat freight }}</span>
</td>
</tr>
<tr>
<th style="text-align: right;">Total</th>
<td style="text-align: left;">
<span class="spnContinued" style="background-color: yellow;">Continued...</span>
<span class="spnTotal"><strong>${{numberFormat (getFinalAmount items
freight)}}</strong></span>
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
<p style="margin:0; text-align:center"><span class="pageNumber"></span></p>
</section>
<!-- footer end -->
<section id="main">
<div class="chapter"
style="width: 195mm; height: 148.5mm; border-left: solid 1px black; border-right: solid 1px black;">
<table id="tblMain" class="tableStripe" cellpadding="0" cellspacing="0" style="width:100%;">
{{#each items}}
<tr>
<td>{{quantity}}</td>
<td>{{name}}</td>
<td>${{numberFormat price}}</td>
<td>${{numberFormat (getTotal quantity price) }}</td>
</tr>
{{/each}}
</table>
</div>
</section>
</body>
</html>
PDF.co Web API: the Web API with a set of tools for documents manipulation, data conversion, data extraction, splitting and merging of documents. Includes image recognition, built-in OCR, barcode generation and barcode decoders to decode bar codes from scans, pictures and pdf.
Download Source Code (.zip)
return to the previous page explore PDF from HTML Template endpoint
Copyright © 2016 - 2023 PDF.co