JavaScript Mapping Library
Today’s BoxLang quick tip is one near and dear to my heart, generating PDFs. Creating dynamic, expressive PDFs is fairly easy. Let me show you how. As before, I’ve got a video version as well so you would rather watch that, just skip to the end.
By default, BoxLang doesn’t ship with PDF capabilities built-in, you need to add it via the PDF Module. This can be done quickly via the CLI:
install-bx-module bx-pdf
Installing the module adds three new tags to your BoxLang runtime:
Check the docs for full syntax information.
How about the simplest demo possible?
<bx:document filename="test1.pdf" overwrite=true> <h2>Hello World</h2> <p> This will be a PDF. Enjoy! </p> </bx:document>
In this example, the template will use the content within, static HTML, and save it to test1.pdf. Note the use of overwrite=true. Without it, you would get an error if you run the code again. You can actually skip saving the data to the filesystem and instead store the binary data by using the variable attribute instead.
test1.pdf
overwrite=true
variable
And the result:
We can make it a bit more interesting by adding some media. Consider this:
<bx:document filename="test2.pdf" overwrite=true localUrl=true> <h2>Hello World</h2> <p> This will be a PDF. Enjoy! </p> <p> <img src="./cat.jpg"> </p> <p> Photo by <a href="https://unsplash.com/@dariasha911?utm_content=creditCopyText&utm_medium=referral&utm_source=unsplash">Daria Shatova</a> on <a href="https://unsplash.com/photos/white-and-brown-cat-lying-on-brown-wooden-floor-46TvM-BVrRI?utm_content=creditCopyText&utm_medium=referral&utm_source=unsplash">Unsplash</a> </p> </bx:document>
Note that I’m using a local image, cat.jpg, and in order for the BoxLang PDF tool to find it, I added localUrl to the tag. This generates pretty much what you would expect – a PDF with a cat picture. (Which improves every PDF I’ve found.)
cat.jpg
localUrl
Ok, so far, these have been static, simple PDFs. How about a more complex example? Consider this script:
<bx:script> seed = [ {name:'Raymond Camden', title:'Jedi Evangelist', salary: 300000, location:'Lafayette, Louisiana'}, {name:'Todd Sharp', title:'Ninja Advocate', salary: 425000, location:'Atlanta, Georgia' }, {name:'Scott Stroz', title:'Giant Evangelist', salary: 400000, location:'West By-God Virginia' }, {name:'Brian Rinaldi', title:'Uberino Advocate', salary: 350000, location:'Seattle, Washington' }, ]; </bx:script> <bx:loop array="#seed#" item="person"> <bx:document filename="#slugify(person.name)#.pdf" overwrite=true localUrl=true> <bx:output> <h2>Employment Offer</h2> <p> Hello #person.name#, </p> <p> We are pleased to offer you a job as #person.title# at the salary of #currencyFormat(person.salary)#. </p> <p> You will work out of our #person.location# office. </p> <bx:documentitem type="pagebreak"> <p> Boring legal stuff here no one will read. </p> <bx:documentitem type="footer"> Generated at #dateformat(now(),"short")#. </bx:documentitem> </bx:output> </bx:document> </bx:loop> Done generating PDFs.
I begin with a bit of data, hard-coded, but obviously could have come from a database or API call. It’s got an array of people including names, titles, salaries, and locations. For each of the people, I want to create a unique, dynamic PDF. To do so, I use the built-in slugify function on the name.
Inside the PDF, you can see the use of pound-wrapped variables for my dynamic content. I then use documentitem to create a page break for the second bit of content, legal information no one will read.
documentitem
Finally, I use documentitem again to create a dynamic timestamp value in the footer. And here’s one of the results:
You can find these demos, and the PDF results, in the BoxLang demos repo here: https://github.com/ortus-boxlang/bx-demos/tree/master/boxlang_quick_tips/pdf
Enjoy the video version below:
Raymond Camden
You must be logged in to post a comment.
This site uses Akismet to reduce spam. Learn how your comment data is processed.