Generating a Simple Report with jsreport and express.js: The Lazy Way
Onwuka David
Posted on July 20, 2024
Ever heard of the term "lazy programmer"? π¦₯:) I recently heard that being one is actually a good thing. You may ask why. Well, It is actually not so difficult to understand.
A "lazy programmer" is a term often used humorously to describe a programmer who strives to achieve maximum efficiency with minimal effort. The idea is that by being "lazy," they focus on writing clean, maintainable, and reusable code to avoid repetitive tasks.
That is the idea here. You need to quickly generate a report using jsreport? Then this article is for you.
What you'll need
To follow up with this tutorial, you'll need these:
Latest version of Node.js and npm installed on your computer
A basic knowledge of HTML, CSS, and Javascript
A basic knowledge of Express.js
You are sure you've met the requirements above? Let's go then.
Installing jsreport
So first, we'll need to install and configure jsreport. Head over to https://jsreport.net
Click on "Download" and you'll be taken to their download page.
You'll notice that there are popular platforms installation manuals which you can follow depending on the platform you are using. For this tutorial, we are going to be using Windows, so click on the Windows icon and let's start the installation process.
Go to the command prompt on your desktop and type this to create a folder called "jsreportapp"
mkdir jsreportapp
Then we move into that folder by typing this on the command prompt:
cd jsreportapp
Next, we install jsreport:
npm i -g @jsreport/jsreport-cli
This command will install the jsreport service for you to use on the already created "jsreportapp" folder.
Next command to run would be one to initialize jsreport in your app:
jsreport init
We are now going to run a command to configure the jsreport service according to our needs:
jsreport configure
This will pop up some questions for you to answer. Your answers should depend on what you are using the service for. Since we are trying to create a quick report generating service, We're going to make things as simple as possible. π
See a snapshot below of what we are working with. Feel free to customize yours according to your preferences.
Now, we finish our installation process by running this command:
jsreport start
Now you should be able to open a browser and reach your jsreportapp locally on the port you set for yourself earlier. In this case, it is going to be at: http://localhost:5488
Building a local server
For this, our basic knowledge of Express.js would be really useful. To create a local server, head over to the command prompt and run this:
mkdir my-express-app
cd my-express-app
npm init -y
The command above creates a new directory for your local server, navigates into that directory and runs "npm init" to create a package.json file. You can accept the default settings or customize them as needed.
Next we install Express:
npm install express
Having installed express, open your folder with your preferred code editor, create a file called "index.js" and add up the code below to set up your basic express server:
import express from "express";
const app = express();
const port = 3000;
app.get('/', (req, res) => {
res.send('Hello, World!');
});
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});
Notice that the code above uses ES6 modules instead of Commonjs. So you may want to resolve this before moving on.
Afterwards, start your express server by running the following command in your terminal:
node index.js
You should see a message indicating that the server is running. Open your browser and go to http://localhost:3000 to see the "Hello, World!" message.
Generating a report
Now we are going to generate a simple downloadable html report. To do this, we create a "public" folder in our "my-express-app" folder. In the public folder, we then create an "index.html" file. So head over there and paste this simple report template:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
body {
font-family: Arial, sans-serif;
}
.report {
max-width: 800px;
margin: 0 auto;
padding: 20px;
background-color: #f9f9f9;
border: 1px solid #ddd;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
h1,
h2,
h3 {
color: #333;
}
p {
line-height: 1.6;
margin-bottom: 10px;
}
</style>
</head>
<body>
<div class="report">
<h1>Monthly Report</h1>
<p>This is a simple HTML report template.</p>
<h2>Summary</h2>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec malesuada
magna eu libero lacinia ultrices.
</p>
<h2>Details</h2>
<ul>
<li>Item 1: Description of item 1</li>
<li>Item 2: Description of item 2</li>
<li>Item 3: Description of item 3</li>
</ul>
<h2>Conclusion</h2>
<p>
Nulla facilisi. Vestibulum ante ipsum primis in faucibus orci luctus et
ultrices posuere cubilia curae.
</p>
</div>
</body>
</html>
Navigate to your "index.js" file and import the following modules:
import { dirname } from "path";
import { fileURLToPath } from "url";
import jsreportClient from "@jsreport/nodejs-client";
import fs from "fs/promises";
import path from "path";
Next, copy the code below to handle the report generation functionality
// Initialize the client with the server URL: This will link the express server to the jsreport server
const client = jsreportClient("http://localhost:5488/");
// programatically derives the file path
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// Function to read the HTML template file
async function readHtmlTemplateFile(filename) {
try {
const filePath = path.join(__dirname, "/Public/index.html"); // Specifies the path to the html file
const htmlContent = await fs.readFile(filePath, "utf8");
return htmlContent;
} catch (err) {
throw new Error(`Error reading HTML template file: ${err.message}`);
}
}
// Handle GET request for /report route
app.get("/report", async (req, res, next) => {
try {
const htmlContent = await readHtmlTemplateFile("report-template.html");
const response = await client.render({
template: {
content: htmlContent, // Pass the HTML content read from the file
recipe: "html", // This specifies the recipe as 'html'
engine: "none", // No templating engine used ('none' for static HTML)
},
});
// Set headers to indicate file download
res.setHeader("Content-Disposition", 'attachment; filename="report.html"');
res.setHeader("Content-Type", "text/html");
response.pipe(res); // Stream HTML directly to the client for download
// Pipe the response to the client
response.pipe(res);
} catch (err) {
next(err); // Pass any errors to Express error handling middleware
}
});
The final javascript code in the "index.js" file should look like this:
import express from "express";
import { dirname } from "path";
import { fileURLToPath } from "url";
import jsreportClient from "@jsreport/nodejs-client";
import fs from "fs/promises";
import path from "path";
const app = express();
const port = 3000;
// Home
app.get("/", (req, res) => {
res.send("Hello, World!");
});
// Initialize the client with the server URL: This will link the express server to the jsreport server
const client = jsreportClient("http://localhost:5488/");
// programatically derives the file path
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// Function to read the HTML template file
async function readHtmlTemplateFile(filename) {
try {
const filePath = path.join(__dirname, "/Public/index.html"); // Specifies the path to the html file
const htmlContent = await fs.readFile(filePath, "utf8");
return htmlContent;
} catch (err) {
throw new Error(`Error reading HTML template file: ${err.message}`);
}
}
// Handle GET request for /report route
app.get("/report", async (req, res, next) => {
try {
const htmlContent = await readHtmlTemplateFile("report-template.html");
const response = await client.render({
template: {
content: htmlContent, // Pass the HTML content read from the file
recipe: "html", // This specifies the recipe as 'html'
engine: "none", // No templating engine used ('none' for static HTML)
},
});
// Set headers to indicate file download
res.setHeader("Content-Disposition", 'attachment; filename="report.html"');
res.setHeader("Content-Type", "text/html");
response.pipe(res); // Stream HTML directly to the client for download
// Pipe the response to the client
response.pipe(res);
} catch (err) {
next(err); // Pass any errors to Express error handling middleware
}
});
app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});
Next is to restart your express server:
node index.js
Once it has been restarted without any issues, head over to your browser and naviagte to http://localhost:3000/report
This would download a simple HTML report for you, that you can preview immediately.
That's it guys! There you go! A lazy programmer's approach to generating reports using the jsreport service. π
I'll see you soon with another article. π
Posted on July 20, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.