How to Use a JavaScript Reporting Tool in Your Rust Web Application
ActiveReportsJS is a 100% client-side reporting tool with zero server dependencies. It means that you can use ActiveReportsJS together with any web server, including a Rust application. This article contains a simple yet thorough tutorial on integrating ActiveReportsJS with a Rust application. By the end, you will be able to do the following:
Ready to test out a JavaScript Reporting Tool in Your Rust Web Application? Download ActiveReportsJS Today!
Prerequisites
The following content assumes that you have Rust installed on your machine. If you don't have it, follow the official Rust installation guide. It would be best if you also had ActiveReportsJS installed on your machine. You can obtain it from the ActiveReportsJS website if you don't have it.
Create a Rust Application
To create a new Rust application, run the following command from a terminal or command prompt.
cargo new ReportingOnRust
Then open the newly created ReportingOnRust directory in your favorite code editor, such as Visual Studio Code, and add the following dependencies to the Cargo.toml file.
[dependencies]
actix-web = "*"
actix-files = "*"
serde = { version = "*", features = ["derive"] }
csv = "*"
rustc-serialize = "*"
Add Application Data
We will use the Sales dataset you can download from the E for Excel website. It offers datasets of various sizes, starting from 100 records to 5M records. We will use the first dataset, which has 100 records, for simplicity.
Download and unzip the data from the 100-Sales-Records.zip archive into the "data" folder(it needs to be created) of the application.
There are many fields in the dataset, but we will only use several of them in this tutorial. Add the sale.rs file into the src folder of the application and add the following code:
use serde::Deserialize;
use serde::Serialize;
extern crate csv;
#[derive(Serialize, Deserialize)]
pub struct Sale {
#[serde(rename = "Region")]
region: String,
#[serde(rename = "Item Type")]
item_type: String,
#[serde(rename = "Units Sold")]
inits_sold: i32,
}
pub fn get_sales() -> Result<Vec<Sale>, &'static str> {
let reader = csv::Reader::from_path("data/100 Sales Records.csv");
if reader.is_ok() {
let mut sales: Vec<Sale> = Vec::new();
for result in reader.unwrap().deserialize() {
if result.is_ok() {
let record: Sale = result.unwrap();
sales.push(record);
}
}
Ok(sales)
} else {
Err("can't read the data file")
}
}
Configure JSON API Endpoints
Open the src\main.rs file of the application and replace its content with the following code:
use actix_web::{get, web, App, HttpServer, Responder, Result};
mod sale;
#[get("/sales")]
async fn sales() -> Result<impl Responder> {
let sales = sale::get_sales();
if sales.is_ok() {
Ok(web::Json(sales.unwrap()))
} else {
Ok(web::Json(vec![]))
}
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.service(sales)
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}
Run the application using the cargo run command and open the browser to http://127.0.0.1:8080/sales to see the data the JSON API returns.
Create an ActiveReportsJS Report
Let's create a report that visualizes the data from the JSON API.
In the Standalone Report Designer Application, click the File menu and select the Continuous Page Layout template for a newly created report.
Open the Data panel of the property inspector and click the Add button.
In the Data Source editor dialog, type http://127.0.0.1:8080/sales in the ENDPOINT field and click the Save Changes button.
Click the + icon near DataSource in the Data panel.
In the Data Set Editor dialog, type Sales in the NAME field and $.* in the JSON Path field.
Click the Validate button, ensure that the DataBase Fields section displays [3 items] text, and click the Save Changes button.
Expand the toolbox using the Hamburger menu on the left side of the toolbar.
Drag and drop the Chart item from the toolbox to the report page area's top-left corner. The Chart Wizard dialog appears. On the first screen, select the Bar type and click the Next button.
On the second screen of the dialog, configure the data as shown in the following image and click the Next button.
On the third screen, click the Finish button.
Resize the chart report item so that it fills the entire width of the report page. Click the chart legend to load its properties into the properties panel, and set the Orientation property to Horizontal and Position property to Bottom.
Click the File menu and save the newly created report in the application's static folder (it needs to be created) under the name SalesReport.rdlx-json.
Create and Serve a Static HTML Page to Display the Report
In the static folder of the application, create the index.html file and add the following content to it.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sales Report</title>
<link
rel="stylesheet"
href="https://cdn.grapecity.com/activereportsjs/3.latest/styles/ar-js-ui.css"
type="text/css"
/>
<link
rel="stylesheet"
href="https://cdn.grapecity.com/activereportsjs/3.latest/styles/ar-js-viewer.css"
type="text/css"
/>
<script src="https://cdn.grapecity.com/activereportsjs/3.latest/dist/ar-js-core.js"></script>
<script src="https://cdn.grapecity.com/activereportsjs/3.latest/dist/ar-js-viewer.js"></script>
<script src="https://cdn.grapecity.com/activereportsjs/3.latest/dist/ar-js-pdf.js"></script>
<style>
#viewer-host {
width: 100%;
height: 100vh;
}
</style>
</head>
<body>
<div id="viewer-host"></div>
<script>
var viewer = new ActiveReports.Viewer("#viewer-host");
viewer.open('SalesReport.rdlx-json');
</script>
</body>
</html>
Stop the application and adjust the main.rs file so that it contains the use declaration for actix_files and the static file services:
use actix_files as fs;
use actix_web::{get, web, App, HttpServer, Responder, Result};
mod sale;
#[get("/sales")]
async fn sales() -> Result<impl Responder> {
let sales = sale::get_sales();
if sales.is_ok() {
Ok(web::Json(sales.unwrap()))
} else {
Ok(web::Json(vec![]))
}
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.service(fs::Files::new("/reporting", "./static").index_file("index.html"))
.service(sales)
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}
Run the application again and visit the http://127.0.0.1:8080/reporting/ URL in the browser to see the report. If you followed the steps correctly, you should see a report that displays the data from the JSON API.
Ready to test out a JavaScript Reporting Tool in Your Rust Web Application? Download ActiveReportsJS Today!