Skip to content

PDFDocument: Tips for Using Templates

The PDF Template is not a new feature, but it received a shine in Xojo 2021r3. What’s a PDFDocument template or why would you use them? Let’s look at a couple of scenarios where them are useful including storage, saving time and visual PDF editors.

For Storage

Sure, you can save a PDF created from a PDFDocument instance, as a file or to a database as a binary blob; but you’ll probably save a bunch of bytes if you save the JSON representation of the PDF document provided by the PDFDocument.Template method.

Let’s suppose you want to save these as simple “templates” for your app’s/solutions purposes. The main difference is that if you save these as PDF files, you won’t be able to add new objects / drawing / text or anything PDF-related to them because PDFDocument can’t parse or recreate the required objects from the data streams in the PDF file, so they won’t be able to continue to work with these.

On the contrary, if you save these “templates” to a file or Database using the Template method, you’ll later be able to create a new PDFDocument instance. All you need to do is pass along the saved JSON data to the PDFDocument constructor and voilà! Now you can continue adding new stuff to that new PDFDocument instance: from text to shapes, images, forms or new pages- anything that is supported by PDFDocument.

Because you don’t want to draw all the stuff again

A new PDFDocument instance created from the data received through the Template method means that there is not need to “draw” the PDF again from scratch using Xojo code. The PDFDocument constructor will take care of the all the needed steps in order to recreate the required objects from the received data.

You may think, “Well, my app already has the code needed to draw that same PDF documents”. Maybe that’s true for some scenarios, but not for all.

For example, what about a solution whose main app is in charge of drawing these base PDF documents or “templates” via code, later saving them to a database? Then, the client app will be able to simply get the PDF “template” they need from the database, create a new PDFDocument instance from that data, and add all the new stuff they need … without relying in the code that was needed to create the base PDF document in first place.

You want to offer a visual PDF Editor to your users

Maybe you are thinking about offering your users a visual editor so they can create PDF documents by simply dragging and dropping controls from a panel, just as you do when working with the Layout Editor in the Xojo IDE.

In this case, it is really worth offering your users an option so they can save the PDF document in its current state for a later retrieval; like you would expect from any editor out there in 2021. In that case, and thanks to the PDFDocument.Template method, that is quite easy! Call the method on the PDFDocument instance and save the retrieved JSON data in the file format or database engine you want.

Your users will be able to run your app again a few hours or days, retrieve any of the PDF documents they previously saved and continue working on them in the same point they left!

Quick Example: Working With PDFDocument.Template

Let’s put this feature in practice with a simple example. This example isn’t that useful for a real-world app, but it serves to demonstrate well how PDFDocument.Template works.

So, let’s start with a code snippet that will create a really simple PDFDocument; just some text and a circle in a one-page document:

Var d As New PDFDocument

Var g As Graphics = d.Graphics

g.FontSize = 30
g.DrawText "Hello there!", 50, 100

Var x, y As Double

x = g.Width/2 - 100
y = g.Height/2 - 100

g.DrawingColor = Color.Red
g.Transparency = 50.0

g.FillOval(x,y,200,200)

Var f As FolderItem = SpecialFolder.Desktop.Child("SamplePDF.pdf")
d.Save(f)
f.Open

This is the how that PDF document will look; not too impressive, but it works for the example purpose:

Now let’s add a line of code to get the “template” data from that document:

Var template As JSONItem = d.Template

And this is how the JSON data will look for that document:

{"General":{"Author":"","Creator":"Xojo","Keywords":"","Subject":"","Title":""},"Document":{"Compression":true,"EmbeddedFonts":false,"Landscape":false,"Width":612.0,"Height":792.0},"Actions":{"0":{"FontSize":"30.00"},"1":{"DrawText":"Hello there!,_ENDTEXT_,50.00,100.00,.00,False"},"2":{"Color":"&h00FF0000"},"3":{"Transparency":".50"},"4":{"FillOval":"206.00,296.00,200.00,200.00"}},"Images":{}}

A mere 396 bytes if we decide to save that data as text to a file. In comparison, our example PDF file is 1,380 bytes in length at this point.

Now let’s create a new PDFDocument instance from that template. All we need is to add this line to the existing code:

Var d2 As New PDFDocument(template)

And this is how it will look-like if we decide to save (and open) it:

Var f2 as FolderItem = SpecialFolder.Desktop.Child("SamplePDFFromTemplate.pdf")
d2.save(f2)
f2.Open

Not very surprisingly, we get the same PDF contents. After all, we created it from a … well … template.

The main point here is that we can continue working with the d2 instance, adding new stuff to it if we want to. Let’s change that second snippet of code a bit:

Var template As JSONItem = d.Template

Var d2 As New PDFDocument(template)
Var g2 As Graphics = d2.Graphics
g2.DrawText "Hi From The Template!", 50, 160

Some interesting things happen here. First of all, you didn’t need to set the font size because it is using the last FontSize value set in the original document where we got the Template data. That’s the same as the color used in drawing the text on the new PDFDocument instance- it is using the last DrawingColor set in the original document.

So, from this point on we can add anything we want to to our new PDFDocument created from the template! You may think about having the first snippet of code in one “main” app (the one we used to create the original PDF document plus the template data), and the second snippet of code only executed by your “client” apps (the one creating a second PDFDocument instance from the Template data).

Learn more about PDFDocument in the Xojo Documentation.

Paul learned to program in BASIC at age 13 and has programmed in more languages than he remembers, with Xojo being an obvious favorite. When not working on Xojo, you can find him talking about retrocomputing at Goto 10 and on Mastodon @lefebvre@hachyderm.io.