Building modern applications has become easier for feature teams, because of wonderful frameworks like Spring Boot, Angular, ReactJS, and Vue.  Services from Amazon, Heroku, Microsoft, and even Google have provided exciting options to further compliment the modern application experience.  However, the need for a rich output format (PDF or Microsoft Excel [XLS] ) seems to remain a few steps behind everything else.  Complex designs in CSS are often the go-to architecture, however, these can become challenging to understand and support.

One would think this is a clear indicator that rich output is becoming less of a need as the application experience evolves.  However, these needs continue to remain on the feature list from applications of all sizes.  In fact, the Fitness Application I am currently building needs to produce invoices in a PDF format. Tax-preparation software requires print quality output for either manual filing or for future reference.  XLS extractions are a must for applications that provide a great deal of data.

After realizing that rich output is still a valid need, I investigated a product called DocRaptor.

About DocRaptor

I first looked into several open source solutions for creating my PDFs, but quickly realized they couldn’t handle the complexity, nor the (hopeful!) scale that I would need.  Instead I found what seemed like a perfect solution: DocRaptor.  It is based on Prince, an industry-proven, feature-rich engine that performs the conversion; however, Prince does not have a service offering on top to provide easy access to this engine.

DocRaptor is a SaaS solution on top of the engine with APIs that support various languages, including:

  • C#
  • Java
  • Node
  • PHP
  • Python
  • Ruby

There is also a RESTful URI, which can be called using a simple cURL command:

In the example above, the template data in the invoice.html file is used to produce a simple PDF called docraptor.pdf.  You can even try the cURL command above, which will produce a PDF similar to below:

The Need

To try out DocRaptor, I wanted to create a full-stack application experience using Spring Boot and Angular.  The Spring Boot RESTful service would introduce a service to provide a list classic rock and roll performers.  The Angular application would display these performing artists in a table format.

On the same display, I added a button to create a PDF version of the list.  The use of this button will make a RESTful call to the Spring Boot API.  In turn, the DocRaptor SaaS solution will generate a PDF version of the table output.  The example PDF will test the capabilities of the convertor engine by duplicating the table across two pages with the following features:

Page #1

The first page will contain the following elements:

  • utilize portrait orientation
  • a watermark (but only available when test-mode is set to false)
  • lower-case roman numeric page numbering
  • page numbering at the bottom of the page (footer)

Page #2

In order to demonstrate the power and flexibility with DocRaptor, the second page will contain::

  • landscape orientation
  • no watermark will appear on the second page
  • two-digit standard page numbering
  • page numbering at the top of the page (header)

The Approach

DocRaptor expects HTML format to produce PDF or XLS documents.  In this example, the Spring Boot service will act as the integration point for DocRaptor.  As such, Spring Boot must gather the necessary data and format the source as HTML so that DocRaptor can return it as a byte[].

Here are the contents from the DocRaptor file:

Everything that DocRaptor needs to convert HTML to a PDF is within this file.  Of course, it is possible to link to external styling files to avoid duplicating efforts.

Setting Up the Spring Boot Service With DocRaptor

Adding DocRaptor to a Spring Boot instance is as simple as adding the following dependency:

The Spring Boot service for this example includes an in-memory H2 database and is populated with a small list of classic rock and roll artists.  For this data, the following Entity object exists:

When combined with a RESTful URI in the ArtistController, a simple GET command to the artists path provides data similar to the list below:

Configuring DocRaptor Inside Spring Boot

The following attributes are required to interact with the DocRaptor service:

  • ${DOCRAPTOR_API_KEY} – API key provided for a new account [doc-raptor.api-key]
  • ${DOCRAPTOR_TEST_MODE_ENABLED} – determines if test mode is enabled (see below) [doc-raptor.test-mode]
  • ${DOCRAPTOR_USE_JAVASCRIPT} – determines if Javascript is enabled [doc-raptor.use-javascript]
  • ${PORT} – port for Spring Boot service [server.port] (optional, default is 8080)

About doc-raptor.test-mode

By enabling test mode via the ${DOCRAPTOR_TEST_MODE_ENABLED} variable, which maps to [doc-raptor.test-mode], no charges will be incurred against the DocRaptor account.  However, enabling test mode replaces any custom watermarks with a generic DocRaptor watermark.

Keep in mind, it is possible to use a [doc-raptor.api-key] equal to YOUR_API_KEY_HERE. However, in doing so [doc-raptor.test-mode] will always be set to true within the DocRaptor service.

Starting Spring Boot With DocRaptor

With the DocRaptor configuration in place, starting the Spring Boot server with the sample project should yield a start-up screen similar to below:

After  loading, log entries similar to those below should appear:

Creating a Dynamic Template for DocRaptor

In order to create the template for DocRaptor to use, I decided to use j2html.   j2html is an HTML builder that allows  Java programs to produce HTML text.  I added the library to Spring Boot via the following dependency:

Next, I created a very simple static utility class for this example:

While very light on cascading style sheets (CSS) features, this HtmlBuilder class will create the template required by DocRaptor and even allow Artist data to be part of the artifact that will be created.

Creating a DocRaptor Service

You can process the DocRaptor request via a simple public method within the DocRaptorService:

Once the validateRequest verifies the docRaptorRequest it calls the buildDocFromRequest() method:

Within the ArtistService, the following method interfaces with the DocRaptor service:

Then, the ArtistController and the /artists/pdf URI call the service:

Adding a Simple Angular Client

At this point, you can use a simple cURL or Postman request to retrieve the PDF file from DocRaptor via the following command:

However, I wanted to create a very basic Angular application to provide some presentation around the experience.  After building a simple list-artists component, the following screen appears when performing an ng serve from the Angular repository:

This view is a simple list of data from the in-memory H2 database of the Spring Boot service.  The Create PDF located in the top right-hand corner of the application calls DocRaptor and the artists/pdf URI. 

Requesting a PDF

In order for DocRaptor to make the PDF file, the Create PDF button is wired to the following method:

This method calls the artistsService in Angular:

This, in turn, calls Spring Boot, which contacts DocRaptor and returns a PDF in a new window:

Success! In the example above, we see a PDF file. 

As you will see, the first page contains the following elements:

  • portrait orientation
  • a watermark (but only available when test-mode is set to false)
  • lower-case roman numeric page numbering
  • page numbering at the bottom of the page (footer)

The second page contains the following elements: 

  • landscape orientation
  • no watermark appears on the second page
  • two-digit standard page numbering
  • page numbering at the top of the page (header)


In this article, we explored how to create a simple PDF of data contained within a full-stack application using DocRaptor.   If you are interested in the data for this example, check out the following repository:

Initially, I was concerned that I wouldn’t be able to provide a path to an Angular template for  DocRaptor to build the PDF using HTML data.  However,  I quickly realized that is not a DocRaptor use case.  While I can provide invoice information to my client as part of the application, I don’t need a great deal of the printed invoice content inside the view within an application.  Content such as customer and provider information are required when providing a print-quality version of the data.

This rich template data needs to be stored somewhere. Furthermore, the ability to dynamically create these templates fits nicely with the niche that DocRaptor meets.  Of course, the same use case also exists for XLS files.

From a pricing perspective, getting started is free by using the API_KEY=YOUR_API_KEY_HERE in the header of each request.  This will generate a PDF or XML file with all the necessary features but will add a “TEST DOCUMENT” watermark in the output.

Getting started with a free seven-day trial allows the testMode=false functionality to remove such watermarks and allow a custom watermark similar to the one provided in this example.  After the free trial, the Basic plan costs $15 (USD) a month for 125 documents per month.  The price-per-document reduces significantly at the Silver level, which allows for 40,000 documents at a rate of $1,000 (USD) per month.  There are some additional pricing options, including an unlimited version.

In today’s modern application development world, SaaS options provide a mechanism to do something really well at an attractive price.  This allows feature teams to focus on refining business rules and enhancing intellectual property logic within their application.

Have a really great day!

Source link

Write A Comment