eazyreport
v1.2.1
Published
Banded document and invoice report printing and rendering engine. Print templates (.rtpl) with JSON data in any web application.
Maintainers
Readme
eazyreport
Banded report printing and preview engine for web applications. Fill
.rtpltemplates with JSON data and print, preview, or export to PDF with exact millimetre positioning.🌐 Online Template Designer: https://eazyreport.in/
🎨 Visual Template Designer (Free)
Design, test, and export your .rtpl templates visually with millimeter-level precision using the free web designer at:
- Visual Drag-and-Drop Studio: Arrange Report Titles, Page Headers, repeating Data Bands, Footers, and Summaries on true physical paper grids (A4, Letter, Receipt roll, Custom).
- Live Excel / CSV & REST API Ingestion: Connect live REST APIs with custom headers or drop
.xlsxspreadsheets to auto-generate data models. - Barcodes & Charts: Place dynamic QR payment codes, Code 128 barcodes, DataMatrix tags, and SVG charts visually.
- Export
.rtplTemplates: Download.rtplfiles and render or print them in your web application using thiseazyreportpackage.
✨ Features
- 🖨️ Browser-Native Printing: Opens the browser print dialog with exact
@pageprint CSS, margins, and paper sizes (A4, Letter, receipts, label rolls). - 👁️ On-Screen Modal Preview: Call
showPrintPreview(template, data)to display a responsive modal over your app with a rendered document, page count, and "Print" button. - 📦 Zero External Runtime Dependencies: Barcodes (bwip-js), templating (Handlebars), pagination, and styles are bundled inside.
- 🏷️ 28+ Barcodes & 2D Codes: QR codes, Data Matrix, PDF417, Code 128, EAN-13, and more.
- 📊 Rich Band Hierarchy: Report Title, Page Header, Data Bands, Child Bands, Group Headers/Footers, Summary, and Overlays.
- ⚡ Works Everywhere: ESM & CommonJS support for React, Next.js, Vue, Angular, Svelte, or vanilla TypeScript/JavaScript.
🚀 Installation
npm install eazyreport⚡ Quick Start
1. Print Directly (Opens Print Dialog)
Pass your .rtpl template file and data:
import { printReport } from 'eazyreport';
await printReport('/reports/invoice.rtpl', {
invoiceNumber: 'INV-2026-001',
customer: 'Acme Corporation',
items: [
{ description: 'Web Development', qty: 1, price: 1200 },
{ description: 'Cloud Hosting', qty: 12, price: 50 },
],
total: 1800,
});2. Show On-Screen Print Preview Modal
Show an interactive modal dialog directly inside your web application with a rendered preview and a Print button:
import { showPrintPreview } from 'eazyreport';
const preview = await showPrintPreview('/reports/invoice.rtpl', invoiceData, {
companyName: 'My Enterprise',
});
// To programmatically close:
// preview.close();3. Print Directly from Cloud Storage (Zero-File Integration)
Instead of downloading, hosting, or bundling .rtpl template files in your project, save them to EazyReport Cloud directly from the designer and pass the cloud URL or template ID:
import { printReport } from 'eazyreport';
// Option A: Full unique fileId
await printReport('eazyreport.in?fileId=thameempk-k8x2_invoice', invoiceData);
// Option B: With separate userId and fileId
await printReport('eazyreport.in?userId=thameempk-k8x2&fileId=invoice', invoiceData);4. Embed Preview in a Container Element
Render the report inside any <div> element on your page:
import { previewReport } from 'eazyreport';
const container = document.getElementById('report-container');
await previewReport('eazyreport.in?fileId=thameempk-k8x2_invoice', invoiceData, undefined, { container });5. Get Formatted HTML (For PDF Generation / Emailing)
Get the complete HTML string with @page styles and fonts:
import { getReportHtml } from 'eazyreport';
const html = await getReportHtml('eazyreport.in?fileId=thameempk-k8x2_invoice', invoiceData);📄 Template Sources
The template argument supports:
- Cloud Template URL:
'eazyreport.in?fileId=thameempk-k8x2_invoice'or'eazyreport.in?userId=...&fileId=...' - URL string:
'/reports/invoice.rtpl'or'https://example.com/templates/receipt.rtpl' - JSON string:
'{"version": 2, "pages": [...] }' - Parsed JavaScript object: Template loaded via
importor API - File / Blob: Selected from an
<input type="file">or dragged-and-dropped
// From a file input:
const file = fileInput.files[0];
await printReport(file, invoiceData);
// From a fetched object:
import invoiceTemplate from './templates/invoice.json';
await printReport(invoiceTemplate, invoiceData);🔄 Batch Printing (Multiple Records)
Pass an array as the data argument to print one copy of the report per record (page numbers automatically restart for each record):
const invoices = [invoice1, invoice2, invoice3];
await printReport('/reports/invoice.rtpl', invoices);⚙️ Parameters & Extra Data Sources
Pass report parameters and additional data sources:
await printReport(
'/reports/invoice.rtpl',
invoiceData,
// Report parameters:
{
companyName: 'Acme Ltd',
showTaxSummary: true,
},
// Options:
{
sources: {
shipping: logisticsData, // accessible in template as {{shipping.carrier}}
},
copies: 2,
title: 'Customer Invoice #1024',
}
);⏳ High-Performance & Large Dataset Progress Loader
When generating documents with hundreds of pages (such as 500+ page bank statements or bulk invoices), eazyreport automatically runs asynchronous pagination without freezing the browser main thread and displays a built-in progress loader modal:
- Instant Frame-1 Display: The loader modal appears instantly with zero click delay.
- Accurate Percentage (0% to 100%): Multi-pass tracking proportional to actual records paginated.
- Cancellation: Users can click Cancel or use
AbortSignalto stop generation at any time.
Built-in Progress (Automatic)
// Built-in progress loader is enabled by default in browser environments:
await showPrintPreview(template, largeDataSet);
await printReport(template, largeDataSet);Custom Progress Callback & AbortSignal
const controller = new AbortController();
await printReport(template, largeDataSet, params, {
// Hook custom progress bars or UI states:
onProgress: (p) => {
console.log(`${p.percent}% - ${p.pageCount} pages: ${p.message}`);
},
// Set to false if you only want your custom UI:
showProgress: false,
// Programmatically cancel if needed:
signal: controller.signal,
});
// Cancel if user navigates away:
// controller.abort();🧩 Advanced: Fluent ReportBuilder API
For fine-grained control:
import { ReportBuilder } from 'eazyreport';
const builder = new ReportBuilder('/reports/invoice.rtpl')
.data(invoiceData)
.source('logistics', shippingData)
.param('currency', 'USD')
.copies(1)
.title('Invoice 1001');
// Validate before printing
const issues = builder.validate();
if (issues.length) console.warn(issues);
// Print or get page count
console.log('Total pages:', builder.pageCount());
await builder.print();💻 Framework Examples
React
import React, { useState } from 'react';
import { printReport, showPrintPreview } from 'eazyreport';
export function InvoiceButton({ invoice }) {
const [loading, setLoading] = useState(false);
const handlePrint = async () => {
setLoading(true);
try {
await showPrintPreview('/reports/invoice.rtpl', invoice);
} finally {
setLoading(false);
}
};
return (
<button onClick={handlePrint} disabled={loading}>
{loading ? 'Preparing...' : 'Print Preview'}
</button>
);
}Vue 3
<script setup>
import { printReport } from 'eazyreport';
const props = defineProps(['order']);
async function printOrder() {
await printReport('/reports/order.rtpl', props.order);
}
</script>
<template>
<button @click="printOrder">Print Order</button>
</template>jQuery & HTML (Standard <script> Tag)
Include index.umd.js (or via CDN https://unpkg.com/eazyreport):
<!-- 1. Include jQuery -->
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<!-- 2. Include eazyreport (creates window.eazyreport) -->
<script src="path/to/eazyreport/index.umd.js"></script>
<button id="printBtn">Print Invoice</button>
<button id="previewBtn">Preview Invoice</button>
<script>
const invoiceData = {
invoiceNumber: 'INV-1001',
customer: 'Acme Corp',
total: 1250.00
};
const params = {
companyName: 'My Enterprise Ltd'
};
// Direct print on click:
$('#printBtn').on('click', async function() {
await eazyreport.printReport('/reports/invoice.rtpl', invoiceData, params);
});
// On-screen preview modal:
$('#previewBtn').on('click', async function() {
await eazyreport.showPrintPreview('/reports/invoice.rtpl', invoiceData, params);
});
</script>Vanilla JavaScript (ES Module <script type="module">)
<button id="print-button">Print Invoice</button>
<script type="module">
import { printReport, showPrintPreview } from './lib/index.js';
document.getElementById('print-button').addEventListener('click', async () => {
await showPrintPreview('/reports/invoice.rtpl', { total: 450 }, { companyName: 'Acme' });
});
</script>📖 API Reference
printReport(template, data?, params?, options?)
Fills the template and opens the browser's native print dialog.
showPrintPreview(template, data?, params?, options?)
Displays an on-screen preview modal with a "Print" button and page count. Returns { close, iframe, overlay }.
previewReport(template, data?, params?, options?)
Renders the report inside options.container (an HTMLElement) or opens in a new browser tab.
getReportHtml(template, data?, params?, options?)
Returns the complete standalone HTML document string.
countReportPages(template, data?, params?, options?)
Calculates and returns the exact number of pages.
PrintOptions
| Option | Type | Description |
| --- | --- | --- |
| sources | Record<string, any> | Additional data sources mapped by alias (e.g. { shipment: ... }) |
| base | string \| TemplateSource | Base report / letterhead template or 'portrait' / 'landscape' |
| copies | number | Number of copies to print |
| title | string | Document title (sets browser tab / PDF name) |
| calibration | boolean | Whether to apply printer calibration offsets (default true) |
📄 License
MIT © Mohammed Thameem PK
