PDF template created for invoice with optional parameters (for NodeJs). Using jsPDF library.
npm install jspdf-invoice-template-nodejsjsPDF library. ( jsPDF is exported also, so it can be used without importing jsPDF separately. )
npm or in browser via CDN by using jsPDFInvoiceTemplate variable.
sh
npm i jspdf-invoice-template
`
Or for NodeJs:
`sh
npm i jspdf-invoice-template-nodejs
`
Alternatively, load latest version from a CDN:
(Recommended to use a static version (not @latest) to prevent failure when updates are made)
`html
`
javascript
//by importing
import jsPDFInvoiceTemplate from "jspdf-invoice-template";
//or directly in browser
jsPDFInvoiceTemplate.default( propsObject );
//you can either import the OutputType const or jsPDF class if you want to create another PDF from scratch (without using the template)
import jsPDFInvoiceTemplate, { OutputType, jsPDF } from "jspdf-invoice-template";
//or directly in browser
const outputTypes = jsPDFInvoiceTemplate.OutputType;
const jsPDF = jsPDFInvoiceTemplate.jsPDF();
jsPDFInvoiceTemplate.default( propsObject );
`
javascript
const pdfObject = jsPDFInvoiceTemplate(props); //returns number of pages created
//or in browser
var pdfObject = jsPDFInvoiceTemplate.default(props); //returns number of pages created
var props = {
outputType: OutputType.Save,
onJsPDFDocCreation?: (jsPDFDoc: jsPDF) => void, //Allows for additional configuration prior to writing among others, adds support for different languages and symbols
returnJsPDFDocObject: true,
fileName: "Invoice 2021",
orientationLandscape: false,
compress: true,
logo: {
src: "https://raw.githubusercontent.com/edisonneza/jspdf-invoice-template/demo/images/logo.png",
type: 'PNG', //optional, when src= data:uri (nodejs case)
width: 53.33, //aspect ratio = width/height
height: 26.66,
margin: {
top: 0, //negative or positive num, from the current position
left: 0 //negative or positive num, from the current position
}
},
stamp: {
inAllPages: true, //by default = false, just in the last page
src: "https://raw.githubusercontent.com/edisonneza/jspdf-invoice-template/demo/images/qr_code.jpg",
type: 'JPG', //optional, when src= data:uri (nodejs case)
width: 20, //aspect ratio = width/height
height: 20,
margin: {
top: 0, //negative or positive num, from the current position
left: 0 //negative or positive num, from the current position
}
},
business: {
name: "Business Name",
address: "Albania, Tirane ish-Dogana, Durres 2001",
phone: "(+355) 069 11 11 111",
email: "email@example.com",
email_1: "info@example.al",
website: "www.example.al",
},
contact: {
label: "Invoice issued for:",
name: "Client Name",
address: "Albania, Tirane, Astir",
phone: "(+355) 069 22 22 222",
email: "client@website.al",
otherInfo: "www.website.al",
},
invoice: {
label: "Invoice #: ",
num: 19,
invDate: "Payment Date: 01/01/2021 18:12",
invGenDate: "Invoice Date: 02/02/2021 10:17",
headerBorder: false,
tableBodyBorder: false,
header: [
{
title: "#",
style: {
width: 10
}
},
{
title: "Title",
style: {
width: 30
}
},
{
title: "Description",
style: {
width: 80
}
},
{ title: "Price"},
{ title: "Quantity"},
{ title: "Unit"},
{ title: "Total"}
],
table: Array.from(Array(10), (item, index)=>([
index + 1,
"There are many variations ",
"Lorem Ipsum is simply dummy text dummy text ",
200.5,
4.5,
"m2",
400.5
])),
additionalRows: [{
col1: 'Total:',
col2: '145,250.50',
col3: 'ALL',
style: {
fontSize: 14 //optional, default 12
}
},
{
col1: 'VAT:',
col2: '20',
col3: '%',
style: {
fontSize: 10 //optional, default 12
}
},
{
col1: 'SubTotal:',
col2: '116,199.90',
col3: 'ALL',
style: {
fontSize: 10 //optional, default 12
}
}],
invDescLabel: "Invoice Note",
invDesc: "There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary.",
},
footer: {
text: "The invoice is created on a computer and is valid without the signature and stamp.",
},
pageEnable: true,
pageLabel: "Page ",
};
`
typescript
{
pagesNumber: number, // (always) - number of pages
jsPDFDocObject: jsPDF, // if (returnJsPDFDocObject: true) - the doc already created. You can use it to add new content, new pages.
blob: Blob, // if (outputType: 'blob') - returns the created pdf file as a Blob object. So you can upload and save it to your server. (Idea from a comment on Twitter)
dataUriString: string, // if (outputType: 'datauristring')
arrayBuffer: ArrayBuffer // if (outputType: 'arraybuffer')
}
//store it to a variable and use it wherever you want
var pdfCreated = jsPDFInvoiceTemplate.default({ ...parameters });
var blob = pdfCreated.blob;
//...
var pagesNum = pdfCreated.pagesNumber;
var pdfObject = pdfCreated.jsPDFDocObject;
`
typescript
//example: create a PDF using the template
var pdfCreated = jsPDFInvoiceTemplate.default({ ...parameters });
//add new page or new content -> see jsPDF documentation
pdfCreated.jsPDFDocObject.addPage();
pdfCreated.jsPDFDocObject.text("Test text", 10, 50);
//...
pdfCreated.jsPDFDocObject.save(); //or .output('');
`
property arrow function to hook into configuring the jsPDF functionality as soon as it's initialized.
Allowing the support of multiple languages and currencies for your invoice as outlined in jsPDF documentation:
> Use of Unicode Characters / UTF-8:
The 14 standard fonts in PDF are limited to the ASCII-codepage. If you want to use UTF-8 you have to integrate a custom font, which provides the needed glyphs.
Example Usage:
`typescript
jsPDFInvoiceTemplate({
//https://github.com/edisonneza/jspdf-invoice-template/issues/20#issuecomment-1859975854
onJsPDFDocCreation: (doc: jsPDF) => {
//var font = "...";
doc.addFileToVFS('LiberationSans-Regular-normal.ttf', font);
doc.addFont('LiberationSans-Regular-normal.ttf', 'LiberationSans-Regular', 'normal');
doc.setFont('LiberationSans-Regular');
},
});
`
npx -p typescript tsc src/index.js --declaration --allowJs --emitDeclarationOnly --outDir dist/src/
npx -p typescript tsc src/index.js --declaration --allowJs --emitDeclarationOnly
``