Use Inkscape and XSLT to Create Cross-Platform Reports and Forms

A way to create platform-independent dynamic forms and reports.

I work for a health-care company developing application software. My colleagues and I are responsible for writing software to process health-care claims, manage work flow and make the company as efficient as possible. We recently decided to replace a piece of third-party software that took health-care claim data and overlaid it on standard HIPAA (Health Insurance Portability and Accountability Act) claim forms. The software would take the data and transpose it into PDF files that we stored on a large file server. Each PDF contained one claim on its proper form. We made the decision to replace the software because we needed something more agile. We wanted something that would create the claim image dynamically and not consume space on our servers.

Figure 1. Health Insurance HCFA 1500 Claim Form

Health-care claims are very intricate (Figure 1). Many boxes and boilerplate text have to be drawn. The conventional way to do this with a software application is to draw a series of lines using coordinates and lengths, and then lay the static and dynamic content on top of the newly drawn lines. The process of programming an application like this is long and tedious, not to mention error-prone. We wanted something that was easier to create and maintain. Our requirements were as follows:

  • We must be able to print high-quality versions of the claims.

  • Claims must be accessible from a Web browser.

  • The solution has to be programming language-independent. We use Python, PHP, Perl and Java. The images need to be created using any of these languages.

  • We must be able to convert the claim data and form into several different file formats, specifically PDF and PNG.

  • The entire solution must be platform-independent.

After reviewing the requirements, we looked at several different open- and closed-source options. None of them met all of our requirements, so we turned to creating our own solution. We tried scanning a blank claim form and using ImageMagick to put the claim data on it. This almost gave us what we wanted. The problem was that it was going to be tedious and redundant to create the solution in all of the required languages. Next, we turned to FOP (Formatting Objects Processor). This solution was closer to what we wanted. However, it would take too long create the claim forms. Plus, the solution was not really language-independent either (FOP is a Java library). We could have written wrappers for the FOP command-line interface, but we were convinced that there was still a better solution.

While exploring the FOP solution, we had the idea of using Scalable Vector Graphics (SVGs). Basically, we would take an SVG image of the claim form and make it into an XSLT (eXtensible Stylesheet Language Transformation), because the SVG format is a special XML format. Then, we would pull the claim data from our database and convert it into an XML string. Using any of our languages, we could then take the XSLT and the XML and create an SVG image of the claim. This solution met all of our requirements. It was language- and platform-independent. We could print the SVG images and embed them into Web pages. Furthermore, SVG images can be converted into different file formats easily. Another nice feature of this solution is the small file size of the SVG images. If we wanted to archive the images, they would take a fraction of the space the old solution did. Because SVG images are text, not compressed binary, the files can be compressed and save even more space.

Creating the Master SVG

One of the things that made the SVG solution so appealing was how easy it would be to create and maintain the master SVG image of the form. To do this, we would use Inkscape. Inkscape is an SVG-authoring tool that works on Linux, Mac OS X, Windows and other UNIX-like operating systems. Other SVG-authoring tools are available, but we chose Inkscape because it is open, and it is in the package manager for most Linux distributions.

The first thing we did to create the master SVG was open Inkscape and create a new US Letter size document. To keep things organized, we created four layers in the new document: scan, overlay, boilerplate and dynamic text. Using the scan layer, we imported a scan of a claim. Doing this allowed us to line up everything on the Inkscape stage without having to measure anything. After importing the image, we locked the layer so that it could not be modified accidentally. Actually, after we were finished with each layer on the SVG, we would lock it to ensure it was not tampered with.

Next, we used the overlay layer to trace all the lines and boxes from the original claim that we imported. This step was a little tricky. When the image we scanned was originally created, the lines were not spaced evenly for one reason or another. We decided to line up things correctly on our version. Fortunately, Inkscape has tools to do this automatically. By selecting all of the objects that needed to be spaced out (Shift-left-click) and using the Align and Distribute dialog (Object→Align and Distribute in the menu), Inkscape fixed the spacing issues. When finished, we had something that looked like Figure 2.

Figure 2. A Trace of the Lines and Boxes from the Claim Form

After drawing all of the lines, it was time to add all the boilerplate text. For this, we used the aptly named boilerplate layer. Before we got started, we decided to remove the scan layer completely, because we no longer needed it. To align the text properly, we used the Guides in Inkscape. Guides are exactly what the name suggests—guide lines that exist only inside of Inkscape for the purpose of aligning objects. To use a guide line, simply click the top or left-hand margin and drag the line into place. To get the most out of the guide lines, we enabled the Snap points to guides feature (File→Document Preferences→Guides). Doing this allowed us to place all of the text exactly in alignment. Figure 3 shows what the SVG looked like after this step.

Figure 3. The Blank Claim Form Completed

Finally, we switched to the dynamic text layer and added placeholders where the claim data would be located. Again, we used the guides to align everything. For the text place holders, we used a single $ for each block of text. Then, to make life easier down the road, we renamed each of the dynamic text objects to something relevant. We did this by left-clicking on the object and going to Object→Object Properties in the menu. Figure 4 shows the final master SVG with the guide lines.

Figure 4. Final Master with Dynamic Text Layer

Creating the master SVG took about four full hours of work. I would venture to guess that it would have taken several days to do this programmatically.



Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

I did this for a few

Satya2's picture

I did this for a few projects and then turned to JasperReports. Keeping the XSLT in sync with the Inkscape SVG was getting to be a pain.

Does everyone have this problem, where people keep entering their life story into a field that has room for a couple of short lines only?


ewalstad's picture

Thanks for the article, Chad.

Are your files available for download? I wasn't able to find them on the LJ site. I'm especially interested in your xe2_claim PL/pgSQL function because my data is also in a PostgreSQL database.



Re: Resources?

cfiles's picture

You are welcome.

I will be glad to post the full SVG. The database stuff is a bit more complicated; it is tied into our main processing system. Basically outside of the database, without the structure and the data, it is useless.

I am going to try to get the guy who wrote it to publish an article about what he did.

Multiple lines

Anonymous's picture

I am interested in figuring out how to fill out a list of items that is variable for each record. Creating a new variable for every blank like in the template will not be a good idea, so how did you accomplished that?

Re: Multiple lines

Cafuego's picture

You create a flowRoot object in inkscape by clicking and dragging the text tool.

This object contains flowPara objects, which are the paragraphs that wrap properly within the defined flowRoot area.

Note you need to set the text-align property to justify manually if you want justified text, the inkscape text properties dialog doesn't allow you to do that (yet).

Can you share a sample hcfa

mak's picture

Can you share a sample hcfa 1500 file with layers? That will help to understand the design.