Blog Post

How to generate PDF event tickets

Illustration: How to generate PDF event tickets

In this blog post, you’ll create an e-ticket from scratch. The example will be a ticket for a music event, but you can follow the example for a variety of situations, such as flight boarding passes, conference tickets, and even lottery tickets!

The example will use Document Engine and introduce the PDF Generation feature, which allows you to describe your content in HTML, style the content with CSS, and describe the page layout in JSON.

Defining the content

You’ll start with a basic layout for the e-ticket. There’ll be no data yet — just the style and content:

<!DOCTYPE html>
<html>
	<head>
		<style>
			body {
				font-size: 16px;
				font-family: 'Helvetica', Arial, sans-serif;
				margin: 0;
			}
			.container {
				width: 602px;
				height: 200px;
				margin: 0 auto;
				border-radius: 4px;
				background-color: #4537de;
				box-shadow: 0 8px 16px rgba(35, 51, 64, 0.25);
			}
			.column-1 {
				float: left;
				width: 400px;
				height: 200px;
				border-right: 2px dashed #fff;
			}
			.column-2 {
				float: right;
				width: 200px;
				height: 200px;
			}
			.text-frame {
				padding: 40px;
				height: 120px;
			}
			.qr-holder {
				position: relative;
				width: 160px;
				height: 160px;
				margin: 20px;
				background-color: #fff;
				text-align: center;
				line-height: 30px;
				z-index: 1;
			}
			.qr-holder > img {
				margin-top: 20px;
			}
			.event {
				font-size: 24px;
				color: #fff;
				letter-spacing: 1px;
			}
			.date {
				font-size: 18px;
				line-height: 30px;
				color: #a8bbf8;
			}
			.name,
			.ticket-id {
				font-size: 16px;
				line-height: 22px;
				color: #fff;
			}
		</style>
	</head>
	<body>
		<div class="container">
			<div class="column-1">
				<div class="text-frame">
					<div class="event">PSPDFKit TALENT SHOW</div>
					<div class="date">26 August, 2021</div>
					<br />
					<div class="name">John Smith</div>
					<div class="ticket-id">#123456</div>
				</div>
			</div>

			<div class="column-2">
				<div class="qr-holder">
					<img src="qr-code.png" width="120px" height="120px" />
				</div>
			</div>
		</div>
	</body>
</html>

When previewed in a browser such as Chrome, you’ll see a page like the following.

Styled Event Ticket

Variable data

You may have noticed there’s lots of data in the ticket that needs to be generated at runtime. Examples of this are the ticket number, the name of the guest, and even the QR code.

That’s where you can use a template. In place of the hardcoded data, you can add placeholders. And at runtime, you can replace the placeholders with the correct data:

...
</head>
<body>
<div class="container">
  <section>
  <div class="qr-holder">
    <img src="{{QR_CODE_IMAGE_PATH}}" width="100px" height="100px">
  </div>
  <div class="event">PSPDFKit Talent Show</div>
  <div class="date">26 August, 2021</div>
  <hr>
  <div class="name">{{NAME}}</div>
  <div class="ticket-id">#{{TICKET_NUMBER}}</div>
  </section>
</div>
</body>
</html>

Now that you’ve added placeholders for the data generated at runtime, you can replace it.

For this example, you’ll use Mustache.js, a templating library that will take the HTML above and replace the placeholders in double curly braces with the data you provide.

Note that this example will be using JavaScript and Node.js. If you’re looking for other language examples, you can find them in the Document Engine guides.

Define your data, which in theory could be pulled from any desired source (database, REST API, local file), and apply that to the template:

const mustache = require('mustache');
const fs = require('fs');

const page = fs.readFileSync('page.mustache').toString();
const ticketData = {
	name: 'John Smith',
	ticket_id: '123456',
	qr_code_image_path: 'qr-code.png',
};

const outputHTML = mustache.render(page, ticketData);

Run the script with Node.js:

node mustache-example.js

You now have your custom e-ticket created in HTML. Next, you’ll pass this to the PDF Generation feature to create a PDF.

PDF generation

The first part is simple. Pass the created HTML to Document Engine’s /api/build endpoint for generation:

curl -X POST http://localhost:5000/api/build \
  -F '[email protected];type=text/html' \
  -F '[email protected];type=image/png' \
  -F instructions='{
  "parts": [
    {
      "html": "page.html",
      "assets": [
        "qr-code.png"
      ]
    }
  ],
  "output": {
    "type": "pdf"
  }
}' \
  -o result.pdf

Along with the HTML, you can see that you passed the qr-code.png image (you can download the QR code from here if you’re following along). This allows the generator to reference the image when generating the PDF.

From the above, you’ll receive the following resulting PDF. But the page is A4 size, which is probably not what you want.

Generated Event Ticket A4

Page size

You can resize the page with the size property in the PDF Generation schema.

Because you’ve already defined your ticket size in HTML as 600px by 200px, you’ll want a similar page size. The PDF Generation schema page size takes values in millimeters, so you’ll have to do the conversion. (More information on conversions can be found in the PDF Generation guides):

(600 / 96) * 25.4 = 158.75 mm
(200 / 96) * 25.4 = 52.91 mm

The page size expects integer value types, so round the results and use a width of 159 and a height of 53 in the PDF Generation schema:

curl -X POST http://localhost:5000/api/build \
  -F '[email protected];type=text/html' \
  -F '[email protected];type=image/png' \
  -F instructions='{
  "parts": [
    {
      "html": "page.html",
      "assets": [
        "qr-code.png"
      ],
      "layout": {
        "size": {
          "width": 159,
          "height": 53
        }
      }
    }
  ],
  "output": {
    "type": "pdf"
  }
}' \
  -o result.pdf

Generated Event Ticket No Margins

This is perfect. But to make things a little cleaner, you can add some white space with page margins — let’s say 5 mm all around.

Page margins

To define margins, add the margin object in the PDF Generation schema with the values required. Then, expand the width and height to account for the margins:

curl -X POST http://localhost:5000/api/build \
  -F '[email protected];type=text/html' \
  -F '[email protected];type=image/png' \
  -F instructions='{
  "parts": [
    {
      "html": "page.html",
      "assets": [
        "qr-code.png"
      ],
      "layout": {
        "size": {
          "width": 169,
          "height": 63
        },
        "margin": {
          "top": 5,
          "left": 5,
          "right": 5,
          "bottom": 5
        }
      }
    }
  ],
  "output": {
    "type": "pdf"
  }
}' \
  -o result.pdf

And now you end up with a nicely sized e-ticket in a PDF, ready to send to your customer!

Generated Event Ticket with Margin

Conclusion

In this post, you created an event e-ticket from scratch. As you can see from this example, it’s possible to create expressive designs and convert these designs to PDFs.

All the areas of the PDF Generation feature discussed in this blog post can be found in our guides. There, you’ll also find more information describing how to further customize your PDFs and edit them after they’re generated.

Author
Nick Winder Core Engineer

When Nick started tinkering with guitar effects pedals, he didn’t realize it’d take him all the way to a career in software. He has worked on products that communicate with space, blast Metallica to packed stadiums, and enable millions to use documents through Nutrient, but in his personal life, he enjoys the simplicity of running in the mountains.

Related products
Share post
Free trial Ready to get started?
Free trial