Skip to main content

Complex Sales Report (Javascript)

This example demonstrates how to generate a complex sales report using the GoTempl engine. The report contains sales data, a dynamic chart using Chart.js, conditionals to display warnings, and loops to generate tables. The layout is styled using Tailwind CSS. This report is generated synchronously via the /generate-pdf-sync endpoint.

Generated complex sales report with tailwind and chartJS to PDF

Step-by-Step Guide:

1. Prepare the HTML Template

This is the GoTempl-based HTML template used to generate the complex sales report. It includes:

  • Charts: Rendered with Chart.js.
  • Conditionals: A warning is shown if the total sales are below a threshold.
  • Loops: Used to generate tables of sales data.
  • Tailwind CSS: For layout and styling.
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<title>Sales Report</title>
<style>
.chart-container {
width: 600px;
height: 400px;
margin: 0 auto;
}
</style>
</head>
<body class="bg-gray-100">
<div class="max-w-4xl mx-auto bg-white p-8 mt-10 rounded-lg shadow-md">
<h1 class="text-3xl font-bold text-center mb-6">Sales Report - {{.Month}} {{.Year}}</h1>

<!-- Conditional: Show message if sales are low -->
{{if lt .TotalSales 1000.0}}
<p class="text-red-500 text-center font-semibold">Warning: Sales are lower than expected this month.</p>
{{end}}

<!-- Sales Data Table -->
<h2 class="text-2xl font-bold mb-4">Sales Data</h2>
<table class="min-w-full table-auto mb-6">
<thead>
<tr class="bg-gray-200">
<th class="px-4 py-2">Product</th>
<th class="px-4 py-2">Units Sold</th>
<th class="px-4 py-2">Revenue</th>
</tr>
</thead>
<tbody>
{{range .SalesData}}
<tr class="border-t">
<td class="px-4 py-2">{{.Product}}</td>
<td class="px-4 py-2">{{.UnitsSold}}</td>
<td class="px-4 py-2">\${{.Revenue}}</td>
</tr>
{{end}}
</tbody>
</table>

<!-- Sales Chart -->
<h2 class="text-2xl font-bold mb-4">Sales Chart</h2>
<div class="chart-container">
<canvas id="salesChart"></canvas>
</div>

<script>
var ctx = document.getElementById('salesChart').getContext('2d');
var salesChart = new Chart(ctx, {
type: 'bar',
data: {
labels: [{{range $index, $element := .ChartData.Labels}}{{if $index}},{{end}}"{{$element}}"{{end}}],
datasets: [{
label: 'Revenue',
data: [{{range $index, $element := .ChartData.Values}}{{if $index}},{{end}}{{$element}}{{end}}],
backgroundColor: 'rgba(54, 162, 235, 0.2)',
borderColor: 'rgba(54, 162, 235, 1)',
borderWidth: 1
}]
},
options: {
scales: {
y: {
beginAtZero: true
}
}
}
});
</script>
</div>
</body>
</html>

2. Submit the Template Using JavaScript

Here’s the JavaScript code to submit the template and generate the PDF using the Fetch API. This will create the sales report asynchronously and store it as complex_sales_report.pdf.

const fetch = require('node-fetch');
const fs = require('fs');

// Define the HTML template (GoTempl)
const htmlTemplate = `
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<title>Sales Report</title>
<style>
.chart-container {
width: 600px;
height: 400px;
margin: 0 auto;
}
</style>
</head>
<body class="bg-gray-100">
<div class="max-w-4xl mx-auto bg-white p-8 mt-10 rounded-lg shadow-md">
<h1 class="text-3xl font-bold text-center mb-6">Sales Report - {{.Month}} {{.Year}}</h1>

<!-- Conditional: Show message if sales are low -->
{{if lt .TotalSales 1000.0}}
<p class="text-red-500 text-center font-semibold">Warning: Sales are lower than expected this month.</p>
{{end}}

<!-- Sales Data Table -->
<h2 class="text-2xl font-bold mb-4">Sales Data</h2>
<table class="min-w-full table-auto mb-6">
<thead>
<tr class="bg-gray-200">
<th class="px-4 py-2">Product</th>
<th class="px-4 py-2">Units Sold</th>
<th class="px-4 py-2">Revenue</th>
</tr>
</thead>
<tbody>
{{range .SalesData}}
<tr class="border-t">
<td class="px-4 py-2">{{.Product}}</td>
<td class="px-4 py-2">{{.UnitsSold}}</td>
<td class="px-4 py-2">\${{.Revenue}}</td>
</tr>
{{end}}
</tbody>
</table>

<!-- Sales Chart -->
<h2 class="text-2xl font-bold mb-4">Sales Chart</h2>
<div class="chart-container">
<canvas id="salesChart"></canvas>
</div>

<script>
var ctx = document.getElementById('salesChart').getContext('2d');
var salesChart = new Chart(ctx, {
type: 'bar',
data: {
labels: [{{range $index, $element := .ChartData.Labels}}{{if $index}},{{end}}"{{$element}}"{{end}}],
datasets: [{
label: 'Revenue',
data: [{{range $index, $element := .ChartData.Values}}{{if $index}},{{end}}{{$element}}{{end}}],
backgroundColor: 'rgba(54, 162, 235, 0.2)',
borderColor: 'rgba(54, 162, 235, 1)',
borderWidth: 1
}]
},
options: {
scales: {
y: {
beginAtZero: true
}
}
}
});
</script>
</div>
</body>
</html>
`;

// Define the sales data and chart data
const requestData = {
html_template: htmlTemplate,
data: {
Month: "October",
Year: "2024",
TotalSales: 1200.00,
SalesData: [
{ Product: "Laptop", UnitsSold: 50, Revenue: 75000 },
{ Product: "Smartphone", UnitsSold: 100, Revenue: 50000 },
{ Product: "Headphones", UnitsSold: 75, Revenue: 11250 }
],
ChartData: {
Labels: ["Laptop", "Smartphone", "Headphones"],
Values: [75000, 50000, 11250]
}
},
engine: 'gotempl', // Use GoTempl engine
};

// API Key
const apiKey = 'YOUR_API_KEY';

// Function to generate the PDF using Fetch API
async function generatePDF() {
try {
const response = await fetch('https://reportgen.io/api/v1/generate-pdf-sync', {
method: 'POST',
headers: {
'X-API-Key': apiKey,
'Content-Type': 'application/json',
},
body: JSON.stringify(requestData),
});

if (!response.ok) {
throw new Error(`Error generating PDF: ${response.statusText}`);
}

const pdfBuffer = await response.buffer();
fs.writeFileSync('complex_sales_report.pdf', pdfBuffer);
console.log('PDF successfully generated and saved as complex_sales_report.pdf');
} catch (error) {
console.error('Error generating PDF:', error.message);
}
}

// Run the function to generate the PDF
generatePDF();

3. Explanation

  • HTML Template: Contains a sales report using conditionals, loops, and chart generation with Chart.js.
  • Tailwind CSS: Used for styling the report layout.
  • JavaScript Code: Submits the HTML template and sales data to the reportgen API using the Fetch API and saves the generated PDF file locally as complex_sales_report.pdf.

4. Running the Script

You can run the script with:

node script.js

Make sure to replace YOUR_API_KEY with your actual API key.