Generate an invoice PDF with Anvil
Tags: tutorial, api, webdev
Published: 2021-04-26 04:38:42


Invoices are an essential part of running any business, but they can be a chore to create invoice PDFs programmatically; running headless chrome is painful, relying on the user's browser is a unreliable, and cobbling together several libraries is time consuming and brittle.

We've created a PDF generation API endpoint to ease this pain. It allows you to create new PDFs from a simple JSON payload.

This guide will walk through how to create a PDF invoice using our PDF generation API endpoint.

## Overview

Our goal is to generate an example invoice that looks like the following:

![PDF invoice example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tez3qva3m1sxo1j1nfgp.png)

We will create a JSON payload step-by-step, then we'll make a POST request to a single REST endpoint: `https://app.useanvil.com/api/v1/generate-pdf`.

This tutorial will cover the following concepts to help you quickly get familiar with the Anvil PDF generation endpoint:

* Building a data payload to generate a dynamic PDF
* Customizing the PDF with your logo
* Adding variable length tables to your PDF

## Get your API key

First, you'll need to get your API key by [signing up](https://app.useanvil.com/signup) for an Anvil account.

Once logged in, you will be directed to copy the API key from your organization’s API settings page. For more information see the [getting started guide](https://www.useanvil.com/docs/api/getting-started#api-key).

## Step 1: Build the data payload

The body of the PDF is specified by an array of JSON objects. In the final generated PDF, each object in the array is rendered as its own section, visually separated from other sections by a small margin.

Each object can have a `label`, `content`, a `heading`, and / or a `table` key depending on the information you want to display.

```js
const data = [{
  "content": "January 30th, 2024",
}, {
  "label": "To",
  "content": "Sally Jones - sally@example.com",
}, {
  "label": "From",
  "content": "Acme Co. - billing@acme.com\n123 Main Street\nSan Francisco CA, 94103",
}, {
  "table": {
    // Bold the first row of the table
    "firstRowHeaders": true,
    // We"ll left align the left column, then right align the others
    "columnOptions": [{}, { "align": "right" }, { "align": "right" }],
    // Here we render our product information
    "rows": [
      ["Description", "Quantity", "Price"],
      ["4x Large wigets in green", "4", "$40.00"],
      ["10x Medium widgets in dark blue", "10", "$100.00"],
      ["6x Small widgets in white", "6", "$60.00"],
      ["", "", "&nbsp;"],
      ["", "**Tax**", "$16.23"],
      ["", "**Total**", "$216.23"],
    ],
  },
}]
```

## Step 2: Add a title and your logo

Next, we need to set the title of the PDF and include a logo. We'll set the `title` and `logo` properties at the root of the JSON payload, then include the data we created in the previous section at the data key.

```js
const generatePayload = {
  // The title at the top of the PDF
  "title": "Acme Co. Invoice - #123",

  // Your logo is displayed in the top right
  "logo": {
    // The URL can be any public image url or a data URI
    "src": "https://yoursite.com/yourlogo.png",
    "maxWidth": 50,
  },

  // The data payload from the last section
  "data": data
}
```

## Step 3: Create the PDF

Finally, it's time to generate the PDF. We'll use the `https://app.useanvil.com/api/v1/generate-pdf` REST endpoint and POST the complete JSON payload we assembled over the last 2 sections. The POST request's response will be the brand new invoice PDF file!

Below are examples of the generate request using our Anvil node library, Postman, and curl.

Option 1. Generating the PDF with the [node-anvil](https://github.com/anvilco/node-anvil) library:

```js
import fs from 'fs'
import Anvil from '@anvilco/anvil'
const apiKey = 'YOUR API KEY'
const anvilClient = new Anvil({ apiKey })
const generatePayload = { ... } // Specified above!
const {
  statusCode,
  data
} = await anvilClient.generatePDF(generatePayload)
console.log(statusCode) // => 200

// `data` will be the PDF raw bytes.
fs.writeFileSync('output.pdf', data, {
  // Saving as raw bytes is important!
  encoding: null
})

```

Option 2. Our [Postman collection](https://documenter.getpostman.com/view/14149649/TVzSjcj6#3bece95a-0a71-42ce-aa78-4d25f80ca406) has a Generate PDF example you can use to generate this invoice. Just paste the `generatePayload` into the body:

![create an invoice in postman](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mfjvngns9956985we9pb.png)

Option 3. Generating the invoice PDF with `curl`:

```sh
curl \
  -X POST \
  -u YOUR_API_KEY: \
  -H 'Content-Type: application/json' \
  -d '{ "title": "Acme Co. Invoice - #123", "data": [ ... ] }' \
  https://app.useanvil.com/api/v1/generate-pdf > invoice.pdf
```

That's it!

## Summary

Now you have an understanding of the concepts needed to generate dynamic PDFs. The most important part is constructing the payload with data from your  system, and then making a single request to Anvil’s PDF generation endpoint.

This is a more reliable, scalable, and consistent way to generate PDFs in your application than using headless chrome, relying on the user’s browser, or managing your own PDF code library. Anvil is here to make PDFs easy, so you can focus on building your application.

## Additional resources

* View the [PDF generation API docs](https://www.useanvil.com/docs/api/generate-pdf)
* Check out the [Anvil API Postman collection](https://documenter.getpostman.com/view/14149649/TVzSjcj6)
* Learn how to [encrypt data](https://www.useanvil.com/docs/api/generate-pdf#encrypting-data-payloads) sent to the PDF generation endpoint

Having trouble? Contact us at [support@useanvil.com](mailto:support@useanvil.com).