v2.2.0
v2.2.0v2.1.0v2.0.0v1.2.0

Get Started With Fixed Layout Reports

Introduction

A fixed layout report is the unique feature of ActiveReportsJS that allows you to control report items' location and dimension with unparalleled accuracy. You can use a fixed layout to replicate pre-printed forms and bind them to the data. The output of such reports is a completed form that you can view in a browser, print, or export to one of the supported formats and share the export output with interested parties. Examples of fixed-layout reports are Purchase Orders, Quotes, Parking Tickets, and others.

In this tutorial, we build the data-bound Invoice Form from the ground up, providing experience with the typical report designing process. By the end, you will be able to do the following:

  • Create a Fixed Layout Report
  • Bind the report to the OData API with multiple endpoints
  • Use the OData $select and $filter query options to reduce the volume of retrieved data
  • Create cascading report parameters for interaction with a report reader
  • Use the OData $expand query option to create nested data sets
  • Configure data binding of the fixed layout
  • Use Image report item to display an embedded image
  • Use TextBox report item to display textual information
  • Configure a fixed table layout to display data in accordance to a pre-printed form layout
  • Display summary fields in the table footer

Upon completion of all tutorial steps, the final report will look like this: live demo.

Prerequisites

The following content assumes that you have the Standalone Report Designer running. Visit the tutorial for detailed information. A stable internet connection is also required to access the Demo Data Hub.

Creating a New Report

In the standalone report designer, click the File menu and select the Fixed Page Layout template for a newly created report. Click anywhere on the gray area around the report layout to load the report properties in the Properties panel. In the Margins section, set the Style property to Narrow to change the report page margins size.

Expand to watch creating a new report in action

Creating a new report

Data Binding

Data binding establishes a connection between a report and the data it displays. In this tutorial, we use the GrapeCity Demo OData API that replicates the well-known Northwind database. It contains the sales data for a fictitious company called Northwind Traders, which imports and exports specialty foods worldwide.

Adding Data Source

You can think of the Northwind OData API as the "database" that you can connect to using its root URL https://demodata.grapecity.com/northwind/odata/v1, and that contains multiple "tables" which presented with endpoints such as /Products, /Customers, and /Orders. You can create a Report DataSource that establishes the connection to such a "database" using the following steps.

  • Open the Data panel of the property inspector and click the Add button.
  • In the Data Source editor dialog, type Northwind in the NAME field and https://demodata.grapecity.com/northwind/odata/v1 in the ENDPOINT field.
  • Click the Save Changes button

Expand to watch adding the data source in action

Adding data source

Adding Supplemental Data Sets

Data Sets represent one or more endpoints of the Data Source. For the Invoice Form report, we need to have access to the data from the /Orders, /Customers and /Products endpoints of the Northwind Data Source that we added in the previous section. First, we add supplemental data sets that we will use to build the cascading parameters user interaction and to resolve the relationships between different data sets.

Use the following steps to add the Customers data set:

  • Click the + icon near Northwind in the Data panel.
  • In the Data Set Editor dialog, type Customers in the NAME field, /Customers in the Uri/Path field, and $.value.* in the Json Path field.
  • By default, each Customer record includes 11 fields, but we don't need them all. Therefore we limit the retrieved fields by applying the OData $select query option via a query parameter
    • Click the + icon on the right side of the Parameters section.
    • Type $select in the Parameter field of the newly added Parameter item.
    • Type CustomerId, CompanyName, Address, City, PostalCode, Country in the Value field of the same Parameter item.
  • Click the Validate button.
  • Ensure that the DataBase Fields section displays [6 items] text.
  • Click the Save Changes button.

Expand to watch adding the data set in action

Adding data set

Next, add the Products data set using the same approach:

  • Click the + icon near Northwind in the Data panel.
  • In the Data Set Editor dialog, type Products in the NAME field, /Products in the Uri/Path field, and $.value.* in the Json Path field.
  • By default, each Product record includes ten fields, but we don't need them all. Therefore we limit the retrieved fields by applying the OData $select query option via a query parameter
    • Click the + icon on the right side of the Parameters section.
    • Type $select in the Parameter field of the newly added Parameter item.
    • Type ProductId, ProductName in the Value field of the same Parameter item.
  • Click the Validate button.
  • Ensure that the DataBase Fields section displays [2 items] text.
  • Click the Save Changes button.

Adding Report Parameter

The Invoice Form that we are building should ask a reader to select a customer and an order and show the invoice for this selection. Using report parameters is the primary method for such user input. Follow the next steps to create the Customer report parameter.

  • In the Data panel click the Add button in the Parameters Section.
  • Type Customer in the Name field and Select Customer in the Prompt field.
  • In the Available Values section select Customers for the Data Set Name, CustomerId for the Value Field, and CompanyName for the Label Field.

Expand to watch adding the report parameter in action

Adding report parameter

Configuring Cascading Parameters

The Customer parameter we introduced pulls the list of available values from the Customers data set. Similarly, the Order parameter we are about to introduce should pull the list of available values from the OrderIds data set that is filtered to include orders for the selected customer only:

  • Click the + icon near Northwind in the Data panel.
  • In the Data Set Editor dialog, type OrderIds in the NAME field, /Orders in the Uri/Path field, and $.value.* in the Json Path field.
  • By default, each Orders record includes 15 fields, but we don't need them all. Therefore we limit the retrieved fields by applying the OData $select query option via the query parameter.
    • Click the + icon on the right side of the Parameters section.
    • Type $select in the Parameter field of the newly added Parameter item.
    • Type orderId in the Value field of the same Parameter item.
  • By default, the Orders data set includes all the orders, but we need to apply the filter according to the selected customer. Therefore we filter the retrieved data using the OData $filter query option via the query parameter. The filter value is bound to the report parameter that we added in the previous step.
    • Click the + icon on the right side of the Parameters section.
    • Type $filter in the Parameter field of the newly added Parameter item.
    • Type CustomerId+eq+'{@Customer}' in the Value field of the same Parameter item.
  • Click the Validate button.
  • In the Parameter Prompt that appears, type ALFKI in the @Customer field and click the Save & Run button.
  • Ensure that the DataBase Fields section displays [1 items] text.
  • Click the Save Changes button.

Next, add the Order parameter:

  • In the Data panel click the Add button in the Parameters Section.
  • Type Order in the Name field and Select Order in the Prompt field.
  • Select Integer in the Data Type drop-down.
  • In the Available Values section select OrderIds for the Data Set Name, OrderId for the Value Field, and OrderId for the Label Field.

You can preview the report output and notice that the Parameters panel appears and asks to select a Customer from the list of pre-determined values. When you choose the customer, their orders display in the available list of the Order parameter drop-down. This flow is what we call Cascading parameters. You can create multiple dependent parameters this way.

Adding Main Data Set

Next, we will add the Orders data set containing the actual data that the report will visualize.

  • Go back to the report design and exit the Parameter Editor by clicking the Left Arrow icon near the EDIT PARAMETER header.
  • Click the + icon near Northwind in the Data panel.
  • In the Data Set Editor dialog, type Orders in the NAME field, /Orders in the Uri/Path field, and $.value.* in the Json Path field.
  • By default, the Orders data set includes data for all the orders, but the report should only display the selected order's data. Therefore we filter the retrieved data by using the OData $filter query option via the query parameter. The filter value is bound to the Order report parameter that we added in the previous step.
    • Click the + icon on the right side of the Parameters section.
    • Type $filter in the Parameter field of the newly added Parameter item.
    • Type OrderId+eq+{@Order} in the Value field of the same Parameter item.
  • Each order contains multiple order details that we can pull by using the $expand query option:
    • Click the + icon on the right side of the Parameters section.
    • Type $expand in the Parameter field of the newly added Parameter item.
    • Type OrderDetails in the Value field of the same Parameter item.
  • Click the Validate button.
  • In the Parameter Prompt that appears, type 10248 in the @Order field and click the Save & Run button.
  • Ensure that the DataBase Fields section displays [15 items] text.
  • Note that the Nested DataSets shows the OrderDetails item. You can click it to review the nested data set configuration. It should contain five fields.
  • Click the Save Changes button.

Fixed Layout Data Binding

The main difference between the continous layout and the fixed layout is that the former is driven by data-bound regions, and the latter is bound to the data on the root level and controls data region layouts. Thus, we establish the data binding for the fixed layout:

  • Switch to the Properties panel in the Property Inspector
  • Click anywhere on the gray area around the report layout
  • In the Data section, select the Orders item in the Data Set Name drop-down
  • In the Group section, expand the Group Expressions editor using the List icon on the right side.
  • Click the Add Item button
  • Click the gray box on the right side of the newly added item and choose the OrderId element in the drop-down menu.

Displaying Invoice Header

The Invoice header should include the company name, logo, order date, order id, and title. We will add the textual information first.

  • Expand the toolbox using the Hamburger menu located on the toolbar's left side.
  • Drag and drop the TextBox item from the toolbox to the report page's top-left corner.
  • Set the following properties for the newly added textbox in the properties panel. It will display the company name.
Property Value
Value Northwind Traders
Text Color #3da7a8
Font Size 22pt
Font Weight Bold
Vertical Align Middle
Left 0in
Top 0in
Width 5in
Height 0.5in
Padding 6pt 2pt 6pt 2pt

Expand to watch adding the Company Name textbox and setting some of its properties in action

Adding header text

In the same manner, add the following text boxes.

Property Order Date textbox Order Id textbox Title textbox
Value {OrderDate} Order Id : {OrderId} Invoice
Text Color #3c3c3c #3c3c3c #3c3c3c
Font Size Leave as default Leave as default 24pt
Font Weight Bold Bold Bold
Vertical Align Middle Middle Middle
Left 0in 0in 0in
Top 0.7in 1in 1.5in
Width 2in 2in 7.5in
Height 0.3in 0.3in 0.5in
Padding 6pt 2pt 6pt 2pt 6pt 2pt 6pt 2pt 6pt 2pt 6pt 2pt

You can now preview the report output, select a customer, their order, click the Preview button and notice that the page displays the selected order id, date, along with company name and title.

Embedding Image

Now, let's add the company logo, but first, we need to embed an image in the report definition. Save the image below to a folder of your choice on your machine(Right-click the image and select the Save Image as item in the context menu)

Northwind Logo

  • Go back to the report design and click anywhere on the gray area around the report layout.
  • In the Layout section of the Properties panel, click the list icon on the right side of the Embedded Images property.
  • In the Open File dialog, select the downloaded image and click the Open button.

Expand to watch embedding the image in action

Adding header text

Displaying image

The embedded image is now part of the report and preserved within the report file. We can use it to display the company logo:

  • Expand the toolbox using the Hamburger menu located on the toolbar's left side.
  • Drag and drop the Image item from the toolbox to the report page's top-right corner.
  • In the Appearance section of the Properties panel, expand the Image Editor using the icon on the right side.
  • Select Embedded in the Source drop-down, Northwind-Logo in the Value drop-down, and image/png in the MIME Type drop-down.
  • Set other properties for the newly added image as per the following table.
Property Value
ImageSizing FitProportional
HorizontalAlignment Center
VerticalAlignment Middle
Left 6in
Top 0in
Width 1.5in
Height 1.5in

Displaying Invoice Addresses

The Invoice should display billing and shipping addresses. We will add several textboxes to show this information, but let's start with the customer's company name. The Orders data set includes the CustomerId field, but not the CompanyName. We will use the Lookup function to resolve the company name by customer id:

  • Expand the toolbox using the Hamburger menu located on the toolbar's left side.
  • Drag and drop the TextBox item from the toolbox to the report page's top-left corner.
  • Set the following properties for the newly added textbox in the properties panel.
Property Value
Value {Lookup(CustomerId, CustomerID, CompanyName, "Customers")}
Text Color #3c3c3c
Vertical Align Middle
Left 0in
Top 2.6in
Width 3.4in
Height 0.3in
Padding 6pt 2pt 6pt 2pt

The Lookup function takes the value of the first argument in the current scope - the CustomerId of the order - finds the row with the same CustomerId value in the Customers data set and returns the corresponding CompanyName value.

You can now preview the report output, select a customer and an order, click the Preview button and notice that the page displays the chosen company name.

Go back to the report design and add the rest of the text boxes for the Bill to address and set their properties as per the following table.

Note: to set the bottom border style, expand the Border Style editor using the icon on its right side and set the value marked with the arrow down icon.

Property Header textbox Address textbox City and Zipcode textbox Country textbox
Value BILL TO {Lookup(CustomerId, CustomerID, Address, "Customers")} {Lookup(CustomerId, CustomerID, City, "Customers")} {Lookup(CustomerId, CustomerID, PostalCode, "Customers")} {Lookup(CustomerId, CustomerID, Country, "Customers")}
Border Width 0.25pt Leave as default Leave as default Leave as default
Bottom Border Style Solid Leave as default Leave as default Leave as default
Border Color Gainsboro Leave as default Leave as default Leave as default
Text Color #3da7a8 #3c3c3c #3c3c3c #3c3c3c
Font Size 12pt Leave as default Leave as default Leave as default
Font Weight Bold Leave as default Leave as default Leave as default
Vertical Align Middle Middle Middle Middle
Left 0in 0in 0in 0in
Top 2.2in 2.9in 3.2in 3.5in
Width 3.4in 3.4in 3.4in 3.4in
Height 0.4in 0.3in 0.3in 0.3in
Padding 6pt 2pt 6pt 2pt 6pt 2pt 6pt 2pt 6pt 2pt 6pt 2pt 6pt 2pt 6pt 2pt

In the same manner, add textboxes for the Ship To address:

Property Header textbox Ship Name textbox Ship Address textbox Ship City and Zipcode textbox Ship country textbox
Value SHIP TO {ShipName} {ShipAddress} {ShipCity} {ShipPostalCode} {ShipCountry}
Border Width 0.25pt Leave as default Leave as default Leave as default Leave as default
Bottom Border Style Solid Leave as default Leave as default Leave as default Leave as default
Border Color Gainsboro Leave as default Leave as default Leave as default Leave as default
Text Color #3da7a8 #3c3c3c #3c3c3c #3c3c3c #3c3c3c
Font Size 12pt Leave as default Leave as default Leave as default Leave as default
Font Weight Bold Leave as default Leave as default Leave as default Leave as default
Vertical Align Middle Middle Middle Middle Middle
Left 3.8in 3.8in 3.8in 3.8in 3.8in
Top 2.2in 2.6in 2.9in 3.2in 3.5in
Width 3.7in 3.7in 3.7in 3.7in 3.7in
Height 0.4in 0.3in 0.3in 0.3in 0.3in
Padding 6pt 2pt 6pt 2pt 6pt 2pt 6pt 2pt 6pt 2pt 6pt 2pt 6pt 2pt 6pt 2pt 6pt 2pt 6pt 2pt

You can now preview the report output, select a customer and an order, click the Preview button and notice that the page displays billing and shipping addresses of the specified order. In most cases, these addresses are the same, but there are some orders where these addresses differ. Try to find them.

Adding Fixed Table

The Orders data set contains the nested OrderDetails data set. We will use the fixed table layout to print the order details:

  • Expand the toolbox using the Hamburger menu located on the toolbar's left side.
  • Drag and drop the Table item from the toolbox to any place in the middle of the report page.
  • Set the following properties for the newly added table in the properties panel.
Property Value
DataSet Name OrderDetails
Left 0in
Top 4in
Width 7.5in
Fixed Height 5.5in

Fixed Height sets the limit for the table's space on the page. If there is more data than the fixed table height can accommodate, they are printed on the new page according to the fixed layout configuration, but we will get to this topic later.

By default, the newly added table has the header, the footer, and the detail rows. We add extra rows into a table footer to accommodate summary values:

  • Click anywhere inside the table so that it displays the columns and rows handlers
  • Right-click the last row handler, go to the Row menu item
  • Increase the counter on the right side of the Insert Row/Below item and then click on it to add two rows.

Expand to watch adding extra table footer rows in action

Adding header text

Formatting Table Columns

The table we are building should display the Product Name in the first column, the Quantity in the second column, the Unit Price in the third column, and the Total in the 4th column. Based on this information, let's set up columns width:

  • Click anywhere inside the table so that it displays the columns and rows handlers
  • Click the first column handler and set its Width to 1.2in in the Properties panel
  • Repeat the step above for the second and third columns
  • Right-click the first column handler and select the Column > Insert Column Left item in the context menu
  • Click the newly added column handler and set its Width to 3.9in in the Properties panel

Expand to watch adding the new column and setting its width in action

Setting columns width

Switch to the TEXTBOX tab in the Properties panel. You can now modify the properties of all the table cells of a selected column. Use the following map to configure text appearance of the table columns:

Property 1st column 2nd column 3rd column 4th column
Border Width 0.25pt 0.25pt 0.25pt 0.25pt
Border Style Solid Solid Solid #Solid
Border Color #e6e6e6 #e6e6e6 #e6e6e6 e6e6e6
Text Align Left Right Right Right
Vertical Align Middle Middle Middle Middle
Format Leave as default Leave as default c2 c2
Padding 6pt 2pt 6pt 2pt 6pt 2pt 6pt 2pt 6pt 2pt 6pt 2pt 6pt 2pt 6pt 2pt

Formatting Table Rows

In the same manner, by clicking row handlers and modifying their properties in the ROW and TEXTBOX tabs of the Properties panel, configure the rows appearance:

Property 1st row 2nd row 3rd row 4th row 5th row
Height 0.4in 0.3in 0.3in 0.3in 0.3in
Background Color #f7f7f7 Leave as Default #f9f9f9 #f9f9f9 #f9f9f9
Text Color #3da7a8 Leave as Default Leave as Default Leave as Default Leave as Default
Font Weight Bold Leave as Default Bold Bold Bold

Displaying tables data

It's time to show order details in the table. Fill the table cells according to the scheme below. You can double-click on a table cell and type a value or paste a copied one.

1st column 2nd column 3rd column 4th column
1st row DESCRIPTION QTY UNIT PRICE TOTAL
2nd row {Lookup(ProductId, ProductId, ProductName, "Products")} {Quantity} {UnitPrice} {Quantity * UnitPrice}
3rd row SUBTOTAL {Sum(Quantity * UnitPrice)}
4th row DISCOUNT {Sum(Quantity * UnitPrice * Discount)}
5th row BALANCE DUE {Sum(Quantity * UnitPrice * (1 - Discount))}

Preview the report output, select the Rattlesnake Canyon Grocery company and order 11077, click the Preview button and notice that the order details data split between two pages because the table has the fixed height that we set at design time earlier.

Adding Overflow Placeholder

When the order details are split among multiple pages, it might be desirable not to print the invoice header on all these pages. It only needs to be shown on the first page of the invoice. To configure this feature, we use the Fixed Layout Overflow.

  • Go back to the report design and click the ADD PAGE button on the design surface's bottom-right corner.
  • Expand the toolbox using the Hamburger menu located on the toolbar's left side.
  • Drag and drop the Overflow Placeholder item from the toolbox to the top-right corner of the report page.
  • Make sure that the Left and Top properties of the overflow placeholder are set to 0in
  • Switch to the Page 1 using the fixed page tabs
  • Click anywhere inside the order details table so that it displays the root handler
  • Click the table handler to load the table in the Properties panel and set its OverflowName property to OverflowPlaceHolder1 that is the name of the newly added overflow place holder. Also, turn on the Repeat To Fill switch.

Expand to watch setting the overflow place holder in action

Setting overflow place holder

Preview the report output, select the Rattlesnake Canyon Grocery company and order 11077, click the Preview button and notice that the order details data split between two pages, but the second page only displays the order details that didn't fit into the first page along with summary values. The overflow place holder has the same height as the table does, and the RepeatToFill property allows to put empty lines to fill the entire available space. If the order details data do not fit on the second page, then the third page will be generated to print the overflow.

The final version of report is available at the demo web-site.