Data Visualization
Scheduled Reports
Convert complex data into clear, actionable PDF reports. Ideal for monthly business reviews, financial statements, performance dashboards, and client reporting.
PDF automation eliminates manual work while guaranteeing professional formatting, faultless data, all whilst making sure you always have reports ready when you need them.
// Generate monthly sales report
// Generate monthly sales report
const generateMonthlyReport = async (month, year) => {
// Aggregate data from your database
const reportData = await db.query(`
SELECT
SUM(revenue) as total_revenue,
COUNT(*) as total_orders,
AVG(order_value) as avg_order_value
FROM orders
WHERE MONTH(created_at) = ? AND YEAR(created_at) = ?
`, [month, year]);
const topProducts = await db.query(`
SELECT
p.name,
SUM(oi.quantity) as units_sold,
SUM(oi.total) as revenue
FROM order_items oi
JOIN products p ON oi.product_id = p.id
JOIN orders o ON oi.order_id = o.id
WHERE MONTH(o.created_at) = ? AND YEAR(o.created_at) = ?
GROUP BY p.id
ORDER BY revenue DESC
LIMIT 10
`, [month, year]);
// Generate PDF report
const response = await fetch('https://dash.liquidtemplater.com/items/template_request', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Content-Type': 'application/json'
},
body: JSON.stringify({
data: {
report: {
title: `Sales Report - ${monthNames[month]} ${year}`,
period_start: new Date(year, month - 1, 1).toISOString().split('T')[0],
period_end: new Date(year, month, 0).toISOString().split('T')[0]
},
metrics: {
total_revenue: reportData.total_revenue,
total_orders: reportData.total_orders,
avg_order_value: reportData.avg_order_value,
revenue_change: calculateChange(reportData, lastMonth)
},
top_products: topProducts,
regions: await getRegionalData(month, year)
},
template: `<!DOCTYPE html>
<html>
<head>
<title>Monthly Sales Report</title>
<style>
body { font-family: Arial, sans-serif; margin: 40px; }
.header { text-align: center; margin-bottom: 30px; }
.metrics { display: flex; justify-content: space-around; margin: 20px 0; }
.metric { text-align: center; padding: 15px; background: #f5f5f5; }
.products { margin-top: 30px; }
table { width: 100%; border-collapse: collapse; }
th, td { padding: 10px; border: 1px solid #ddd; text-align: left; }
</style>
</head>
<body>
<div class="header">
<h1>{{ report.title }}</h1>
<p>Period: {{ report.period_start }} to {{ report.period_end }}</p>
</div>
<div class="metrics">
<div class="metric">
<h3>Total Revenue</h3>
<p>{{metrics.total_revenue}}</p>
</div>
<div class="metric">
<h3>Total Orders</h3>
<p>{{ metrics.total_orders }}</p>
</div>
<div class="metric">
<h3>Average Order</h3>
<p>{{metrics.avg_order_value}}</p>
</div>
</div>
<div class="products">
<h2>Top Products</h2>
<table>
<tr>
<th>Product Name</th>
<th>Units Sold</th>
<th>Revenue</th>
</tr>
{% for product in top_products %}
<tr>
<td>{{ product.name }}</td>
<td>{{ product.units_sold }}</td>
<td>{{product.revenue}}</td>
</tr>
{% endfor %}
</table>
</div>
</body>
</html>`,
type: 'pdf'
})
});
const requestData = await response.json();
const requestId = requestData.data.id;
// Poll for completion
let document_url = null;
while (!document_url) {
await new Promise(resolve => setTimeout(resolve, 2000));
const statusResponse = await fetch(
`https://dash.liquidtemplater.com/items/template_request/${requestId}`,
{
headers: { 'Authorization': 'Bearer YOUR_API_TOKEN' }
}
);
const statusData = await statusResponse.json();
if (statusData.data.result) {
document_url = `https://dash.liquidtemplater.com/assets/${statusData.data.result}?download=true`;
}
}
// Save report and notify stakeholders
await db.reports.create({
type: 'monthly_sales',
month: month,
year: year,
pdf_url: document_url,
generated_at: new Date()
});
await sendReportEmail(document_url, stakeholders);
return document_url;
};
Reports are generated on-demand and stored securely in our German data centers for 7 days. This allows stakeholders to access reports multiple times while ensuring data privacy through automatic deletion.