Convert Reports in FileMaker to Xanadu Web App

By: | On:

  FileMaker to Xanadu  

We've been converting FileMaker databases to Xanadu Web Apps over the past few years. One conversion category is Reports. Reports vary, but there are four types:

  • 'Simple' with zero or minimal parameters with a simple query.
  • 'Flexible' reporting on ad hoc record sets with a simple query.
  • 'Forms' with data placed at specific coordinates.
  • 'Customized' with complex formatting, more than one format, or multiple queries.

For most reports, we use mPDF, a popular open-source PHP library for generating PDFs. We'll create a header, footer, and body in HTML using CSS for the styling and applying the CSS page-break-inside: avoid; to content that should overflow to the next page if it won't fit on the current page. Once the HTML is passed, mPDF generates the PDF and the content flows from page to page. That works great for the Simple and Flexible reports that use the full width of the page.

Reports that are Forms or Customized present a challenge in fitting content to fixed spaces. A Form field must fit in the space provided. Directories of information in columns must flow from one column to another and across pages.

In FileMaker, we have a script to create a Customized Report for a Member Directory. In addition to the column and page flow, the Directory also has an index by Name, an index by Category, and of course page numbers. That's complex formatting!

The FileMaker script gathers each Members Info Into a Card that should appear and sorted by Category and Member Name. In a loop we check if the first Member Card fits on the Page and note the Page Number. That repeats until a Member will not fit on the Page. At this point, we'll know which Member Cards fit on Page 1. The remaining Members are processed ending with a list of Member Cards and the Page Number they are on. That's just the Members Info pages. We still need to create the indexes and add page numbers. We create the Category index starting with Page 1. The Member Name index resumes the Page Numbering using the last page number from the Category index. The we recreate the Member Info using the last page number from the Member Name index. Whew!

I looked into how to do this in PHP, but I learned there's no way to calculate how tall a fixed width div since the HTML is never rendered. It turns out that mPDF has the ability to measure div height. Here's some mPDF code:

$beginY = $mpdf->y; // Store the starting Y position
$mpdf->WriteHTML( $combinedCardsHTML ); // Render the combined cards
$endY = $mpdf->y; // Measure where the content ended
$batchHeight = $endY - $beginY; // Calculate the height of the batch

The PHP to replicate how to determine which Members Info Cards appear on a Page worked out great. In the pic below you can see the red line below the simulated Member Cards that fit into a column. Looking at the red line across the columns you can see where the fit vs not fit break generally is.

Column of Cards The red line marks what will fit vs not fit.