This guide explains how to go from a standard HTML file to a fully featured invoice, making use of all the functionality our PDF generator API provides. For more advanced configuration details such as layout, forms, and headers/footers, refer to the PDF generation developer guide.

Basics of PDF generation

PDF generation enables you to create a completely new PDF from a standard HTML document. You can make use of all the tools, including:

  • CSS for styling
  • Images and fonts
  • HTML forms

The PDF generation API converts these to a PDF. The most basic example generates a PDF with the text “Hello World, I am red!” in large black letters. The text color is addressed in the next section.

To run this, create an index.html file containing the HTML in the same folder as your code. Run the code, and you should get result.pdf with your newly generated PDF.

HTML template section:

<h1>Hello World, I am red!</h1>
<p>And I am green.</p>

Command to generate a PDF file (basic API):

Terminal window
curl -X POST https://api.nutrient.io/processor/generate_pdf \
-H "Authorization: Bearer your_api_key_here" \
-o result.pdf \
--fail \
-F html=@index.html

Advanced API:

Terminal window
curl -X POST https://api.nutrient.io/build \
-H "Authorization: Bearer your_api_key_here" \
-o result.pdf \
--fail \
-F index.html=@index.html \
-F instructions='{
"parts": [
{
"html": "index.html"
}
]
}'

Applying basic styling

Now you have your basic PDF, but in spite of what the text says, it’s all black. Use inline CSS to style your text.

In our example, you can make the heading red and the text below it green. Update your index.html file, adding the inline styles, and run your code again.

HTML template section:

<h1 style="color: red;">Hello World, I am red!</h1>
<p style="color: green;">And I am green.</p>

Command to generate a PDF file (basic API):

Terminal window
curl -X POST https://api.nutrient.io/processor/generate_pdf \
-H "Authorization: Bearer your_api_key_here" \
-o result.pdf \
--fail \
-F html=@index.html

Advanced API:

Terminal window
curl -X POST https://api.nutrient.io/build \
-H "Authorization: Bearer your_api_key_here" \
-o result.pdf \
--fail \
-F index.html=@index.html \
-F instructions='{
"parts": [
{
"html": "index.html"
}
]
}'

Introducing assets

While inline styling is functional, it’s often more efficient to manage styles in an external CSS file. The PDF generation API supports this by enabling you to include multiple assets with your request. To start, create a file named style.css in the same directory as your HTML and paste your styles there.

CSS file:

h1 {
color: red;
}
p {
color: green;
}

To make use of your new style.css file, you’ll have to update your index.html file. When updating your HTML file, refer to the CSS file with just its name. Nested paths aren’t currently supported — use filenames without paths.

HTML template section:

<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<h1>Hello World, I am red!</h1>
<p>And I am green.</p>
</body>
</html>

You’ll also have to include your new CSS file in your request. Add the CSS file both as a request file and in the assets key of your HTML part.

Command to generate a PDF file (basic API):

Terminal window
curl -X POST https://api.nutrient.io/processor/generate_pdf \
-H "Authorization: Bearer your_api_key_here" \
-o result.pdf \
--fail \
-F html=@index.html \
-F style.css=@style.css \
-F data='{
"assets": [
"style.css"
]
}'

Advanced API:

Terminal window
curl -X POST https://api.nutrient.io/build \
-H "Authorization: Bearer your_api_key_here" \
-o result.pdf \
--fail \
-F index.html=@index.html \
-F style.css=@style.css \
-F instructions='{
"parts": [
{
"html": "index.html",
"assets": [
"style.css"
]
}
]
}'

Creating an invoice

With the core building blocks (the HTML and external assets) out of the way, this section shows a real-world example: creating a PDF invoice. You’ll start with the basic invoice and then add some advanced features on top.

First, update your CSS. All the code is taken from the invoice example, but the relevant parts are also duplicated here. Replace the contents of style.css . Define some common styles used throughout the invoice, as well as the styles only applying to the header.

CSS file:

body {
font-size: 0.75rem;
font-weight: 400;
color: #000000;
margin: 0 auto;
position: relative;
}
h2 {
font-size: 1.25rem;
font-weight: 400;
}
h4 {
font-size: 1rem;
font-weight: 400;
}
.page {
margin-left: 5rem;
margin-right: 5rem;
}
.intro-table {
display: flex;
justify-content: space-between;
margin: 3rem 0 3rem 0;
border-top: 1px solid #000000;
border-bottom: 1px solid #000000;
}
.intro-form {
display: flex;
flex-direction: column;
border-right: 1px solid #000000;
width: 50%;
}
.intro-form:last-child {
border-right: none;
}
.intro-table-title {
font-size: 0.625rem;
margin: 0;
}
.intro-form-item {
padding: 1.25rem 1.5rem 1.25rem 1.5rem;
}
.intro-form-item:first-child {
padding-left: 0;
}
.intro-form-item:last-child {
padding-right: 0;
}
.intro-form-item-border {
padding: 1.25rem 0 0.75rem 1.5rem;
border-bottom: 1px solid #000000;
}
.intro-form-item-border:last-child {
border-bottom: none;
}

Next, update your index.html file, adding the invoice numbers, as well as an address block, and some additional data, such as date and type of payment. This example uses only plain HTML.

HTML template section:

<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="page" style="page-break-after: always">
<div>
<h2>Invoice #</h2>
</div>
<div class="intro-table">
<div class="intro-form intro-form-item">
<p class="intro-table-title">Billed To:</p>
<p>
Company Ltd.<br />
Address<br />
Country<br />
VAT ID: ATU12345678
</p>
</div>
<div class="intro-form">
<div class="intro-form-item-border">
<p class="intro-table-title">Payment Date:</p>
<p>November 22nd 2021</p>
</div>
<div class="intro-form-item-border">
<p class="intro-table-title">Payment Method:</p>
<p>Bank Transfer</p>
</div>
</div>
</div>
</div>
</body>
</html>

If you rerun the generation with the new HTML and CSS, you’ll see a nicely formatted invoice header in your PDF.

Command to generate a PDF file (basic API):

Terminal window
curl -X POST https://api.nutrient.io/processor/generate_pdf \
-H "Authorization: Bearer your_api_key_here" \
-o result.pdf \
--fail \
-F html=@index.html \
-F style.css=@style.css \
-F data='{
"assets": [
"style.css"
]
}'

Advanced API:

Terminal window
curl -X POST https://api.nutrient.io/build \
-H "Authorization: Bearer your_api_key_here" \
-o result.pdf \
--fail \
-F index.html=@index.html \
-F style.css=@style.css \
-F instructions='{
"parts": [
{
"html": "index.html",
"assets": [
"style.css"
]
}
]
}'

Now that you’ve got your basic header, make things a bit nicer and add some custom fonts. Much like with the CSS file, place all the fonts you use in the same folder as your HTML file and then add them to your Nutrient DWS API request. The example below is already updated to show you how.

Always refer to assets by their name, as subfolders aren’t supported.

First, add the @font-family definitions to your CSS file. The updated style.css file includes the following information.

CSS file:

@font-face {
font-family: "Inter";
src: url("Inter-Regular.ttf") format("truetype");
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: "Inter";
src: url("Inter-Medium.ttf") format("truetype");
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: "Inter";
src: url("Inter-Bold.ttf") format("truetype");
font-weight: 700;
font-style: normal;
}
@font-face {
font-family: "Space Mono";
src: url("SpaceMono-Regular.ttf") format("truetype");
font-weight: 400;
font-style: normal;
}
body {
font-size: 0.75rem;
font-family: "Inter", sans-serif;
font-weight: 400;
color: #000000;
margin: 0 auto;
position: relative;
}
h2 {
font-family: "Space Mono", monospace;
font-size: 1.25rem;
font-weight: 400;
}
h4 {
font-family: "Space Mono", monospace;
font-size: 1rem;
font-weight: 400;
}
.page {
margin-left: 5rem;
margin-right: 5rem;
}
.intro-table {
display: flex;
justify-content: space-between;
margin: 3rem 0 3rem 0;
border-top: 1px solid #000000;
border-bottom: 1px solid #000000;
}
.intro-form {
display: flex;
flex-direction: column;
border-right: 1px solid #000000;
width: 50%;
}
.intro-form:last-child {
border-right: none;
}
.intro-table-title {
font-size: 0.625rem;
margin: 0;
}
.intro-form-item {
padding: 1.25rem 1.5rem 1.25rem 1.5rem;
}
.intro-form-item:first-child {
padding-left: 0;
}
.intro-form-item:last-child {
padding-right: 0;
}
.intro-form-item-border {
padding: 1.25rem 0 0.75rem 1.5rem;
border-bottom: 1px solid #000000;
}
.intro-form-item-border:last-child {
border-bottom: none;
}

Then add the fonts to your code for making requests. Add the font files in the same folder as your HTML file and CSS file. This way, they can be sent with the request. Refer to the invoice example for fonts.

Add all the font files to the same folder as your index.html and style.css files.

Running the new code displays your custom fonts, giving the invoice a cleaner appearance.

Command to generate a PDF file (basic API):

Terminal window
curl -X POST https://api.nutrient.io/processor/generate_pdf \
-H "Authorization: Bearer your_api_key_here" \
-o result.pdf \
--fail \
-F html=@index.html \
-F style.css=@style.css \
-F Inter-Regular.ttf=@Inter-Regular.ttf \
-F Inter-Medium.ttf=@Inter-Medium.ttf \
-F Inter-Bold.ttf=@Inter-Bold.ttf \
-F SpaceMono-Regular.ttf=@SpaceMono-Regular.ttf \
-F data='{
"assets": [
"style.css",
"Inter-Regular.ttf",
"Inter-Medium.ttf",
"Inter-Bold.ttf",
"SpaceMono-Regular.ttf"
]
}'

Advanced API:

Terminal window
curl -X POST https://api.nutrient.io/build \
-H "Authorization: Bearer your_api_key_here" \
-o result.pdf \
--fail \
-F index.html=@index.html \
-F style.css=@style.css \
-F Inter-Regular.ttf=@Inter-Regular.ttf \
-F Inter-Medium.ttf=@Inter-Medium.ttf \
-F Inter-Bold.ttf=@Inter-Bold.ttf \
-F SpaceMono-Regular.ttf=@SpaceMono-Regular.ttf \
-F instructions='{
"parts": [
{
"html": "index.html",
"assets": [
"style.css",
"Inter-Regular.ttf",
"Inter-Medium.ttf",
"Inter-Bold.ttf",
"SpaceMono-Regular.ttf"
]
}
]
}'

With your invoice looking good, the next feature is fillable forms.

Add forms to your PDF by including regular HTML input tags in your HTML file. Add the following HTML snippet to your index.html file below the div with the intro-table class.

HTML template section:

<!-- Add below the intro-table div -->
<div class="page" style="page-break-after: always">
<div>
<h4>Thank you for your purchase!</h4>
</div>
<div class="form">
<label for="notes" class="label"> Notes: </label>
<input type="text" id="notes" class="border-bottom" value="" />
</div>
<div class="signer">
<div class="form signer-item">
<label for="date" class="label">Date:</label>
<input type="text" id="date" class="border-bottom" value="01/01/2021" />
</div>
<div class="form signer-item">
<label for="signature" class="label">Issued by:</label>
<input type="text" id="signature" class="border" value="Sign Here" />
</div>
</div>
</div>

You can make them look nice by adding some styling for the forms to your CSS file.

Add the following CSS snippet to your style.css file.

Running the generation now creates fillable PDF forms on the second page.

HTML template section:

/* Add below .intro-form-item-border:last-child */
.form {
display: flex;
flex-direction: column;
margin-top: 6rem;
}
.signer {
display: flex;
justify-content: space-between;
gap: 2.5rem;
margin: 2rem 0 2rem 0;
}
.signer-item {
flex-grow: 1;
}
input {
color: #4537de;
font-family: "Space Mono", monospace;
text-align: center;
margin-top: 1.5rem;
height: 4rem;
width: 100%;
box-sizing: border-box;
}
input#date,
input#notes {
text-align: left;
}
input#signature {
height: 8rem;
}

Add headers and footers to your invoice by creating HTML elements with pspdfkit-header or pspdfkit-footer IDs as the first and last elements of the body.

The PDF generator automatically displays these elements on all pages and replaces {{ pageNumber }} and {{ pageCount }} placeholders with correct values.

For this example, add the HTML for the headers shown in the sample code as the first and last elements of the body element in the index.html file.

Include your logo in the header. Download logo.svg from the invoice example and place it in the same folder as your index.html. You can include the logo in the code later.

HTML template section:

<!-- Add as the first element in the body. -->
<div id="pspdfkit-header">
<div class="header-columns">
<div class="logotype">
<img class="logo" src="logo.svg" />
<p>Company</p>
</div>
<div>
<p>[Company Info]</p>
</div>
</div>
</div>
<!-- Add as the last element in the body. -->
<div id="pspdfkit-footer">
<div class="footer-columns">
<span>Invoice</span>
<span>Page {{ pageNumber }} of {{ pageCount }}</span>
</div>
</div>

You should also make sure your headers and footers look good by updating your CSS file one last time. Add the following to your style.css file.

HTML template section:

/* Add below input#signature. */
#pspdfkit-header {
font-size: 0.625rem;
text-transform: uppercase;
letter-spacing: 2px;
font-weight: 400;
color: #8A8680;
margin-top: 2.5rem;
margin-bottom: 2.5rem;
width: 100%;
}
.header-columns {
display: flex;
justify-content: space-between;
padding-left: 2.5rem;
padding-right: 2.5rem;
}
.logo {
height: 1.5rem;
width: auto;
margin-right: 1rem;
}
.logotype {
display: flex;
align-items: center;
font-weight: 700;
}
#pspdfkit-footer {
font-size: 0.5rem;
text-transform: uppercase;
letter-spacing: 1px;
font-weight: 500;
color: #8A8680;
margin-top: 2.5rem;
bottom: 2.5rem;
position: absolute;
width: 100%;
}
.footer-columns {
display: flex;
justify-content: space-between;
padding-left: 2.5rem;
padding-right: 2.5rem;
}

You can now include logo.svg in your request.

This shows how to use all PDF generation features — more specifically, using HTML to define the structure of your PDF, using CSS to style and lay out your content, adding fonts and images to the PDF, and even including fillable forms.

The invoice example includes everything you added till now, and it adds the actual invoice and summary in the middle. It’s a great starting point for your own PDF generation templates. You can also check out all our other fully featured examples here.

Command to generate a PDF file (basic API):

Terminal window
curl -X POST https://api.nutrient.io/processor/generate_pdf \
-H "Authorization: Bearer your_api_key_here" \
-o result.pdf \
--fail \
-F html=@index.html \
-F style.css=@style.css \
-F Inter-Regular.ttf=@Inter-Regular.ttf \
-F Inter-Medium.ttf=@Inter-Medium.ttf \
-F Inter-Bold.ttf=@Inter-Bold.ttf \
-F SpaceMono-Regular.ttf=@SpaceMono-Regular.ttf \
-F logo.svg=@logo.svg \
-F data='{
"assets": [
"style.css",
"Inter-Regular.ttf",
"Inter-Medium.ttf",
"Inter-Bold.ttf",
"SpaceMono-Regular.ttf",
"logo.svg"
]
}'

Advanced API:

Terminal window
curl -X POST https://api.nutrient.io/build \
-H "Authorization: Bearer your_api_key_here" \
-o result.pdf \
--fail \
-F index.html=@index.html \
-F style.css=@style.css \
-F Inter-Regular.ttf=@Inter-Regular.ttf \
-F Inter-Medium.ttf=@Inter-Medium.ttf \
-F Inter-Bold.ttf=@Inter-Bold.ttf \
-F SpaceMono-Regular.ttf=@SpaceMono-Regular.ttf \
-F logo.svg=@logo.svg \
-F instructions='{
"parts": [
{
"html": "index.html",
"assets": [
"style.css",
"Inter-Regular.ttf",
"Inter-Medium.ttf",
"Inter-Bold.ttf",
"SpaceMono-Regular.ttf",
"logo.svg"
]
}
]
}'